diff --git a/libs/spandsp/spandsp-sim/spandsp/g1050.h b/libs/spandsp/spandsp-sim/spandsp/g1050.h index 47e0b131dc..69184dd77c 100644 --- a/libs/spandsp/spandsp-sim/spandsp/g1050.h +++ b/libs/spandsp/spandsp-sim/spandsp/g1050.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: g1050.h,v 1.7 2008/04/17 18:03:23 steveu Exp $ + * $Id: g1050.h,v 1.8 2008/09/09 16:13:12 steveu Exp $ */ /*! \file */ @@ -243,7 +243,7 @@ typedef struct g1050_queue_element_s double departure_time; double arrival_time; int len; - uint8_t pkt[0]; + uint8_t pkt[]; } g1050_queue_element_t; /*! The model definition for a complete end-to-end path */ diff --git a/libs/spandsp/spandsp-sim/spandsp/rfc2198_sim.h b/libs/spandsp/spandsp-sim/spandsp/rfc2198_sim.h index 7a4dd4a552..ceaf433cf0 100644 --- a/libs/spandsp/spandsp-sim/spandsp/rfc2198_sim.h +++ b/libs/spandsp/spandsp-sim/spandsp/rfc2198_sim.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: rfc2198_sim.h,v 1.3 2008/04/17 18:03:23 steveu Exp $ + * $Id: rfc2198_sim.h,v 1.4 2008/09/09 16:13:12 steveu Exp $ */ /*! \file */ @@ -43,7 +43,7 @@ typedef struct rfc2198_sim_queue_element_s double departure_time; double arrival_time; int len; - uint8_t pkt[0]; + uint8_t pkt[]; } rfc2198_sim_queue_element_t; /*! The model definition for a complete end-to-end path */ diff --git a/libs/spandsp/spandsp/global-tones.xml b/libs/spandsp/spandsp/global-tones.xml index d13f73308a..a1012bab93 100644 --- a/libs/spandsp/spandsp/global-tones.xml +++ b/libs/spandsp/spandsp/global-tones.xml @@ -1,5 +1,5 @@ - + diff --git a/libs/spandsp/spandsp/tones.dtd b/libs/spandsp/spandsp/tones.dtd index 6f0fe46ba6..023f8d0783 100644 --- a/libs/spandsp/spandsp/tones.dtd +++ b/libs/spandsp/spandsp/tones.dtd @@ -35,6 +35,7 @@ diff --git a/libs/spandsp/spandsp/tsb85.xml b/libs/spandsp/spandsp/tsb85.xml index 9fdc327a38..30783fd17a 100644 --- a/libs/spandsp/spandsp/tsb85.xml +++ b/libs/spandsp/spandsp/tsb85.xml @@ -1,6 +1,7 @@ + - + @@ -963,6 +964,7 @@ + @@ -2508,6 +2510,7 @@ + @@ -2550,6 +2553,7 @@ + @@ -2589,6 +2593,7 @@ + @@ -2634,6 +2639,7 @@ + @@ -2668,6 +2674,7 @@ + @@ -2701,6 +2708,7 @@ + @@ -2734,7 +2742,9 @@ + + @@ -2744,11 +2754,14 @@ - + + + + @@ -2758,7 +2771,8 @@ - + + @@ -2767,19 +2781,19 @@ - + - + - + - + @@ -2789,7 +2803,7 @@ - + @@ -2798,7 +2812,11 @@ + + + + @@ -2847,7 +2865,9 @@ - + + + @@ -2857,8 +2877,8 @@ - - + + @@ -2895,8 +2915,8 @@ - - + + @@ -5222,7 +5242,10 @@ - + + @@ -5255,7 +5278,8 @@ - + + @@ -5278,7 +5302,7 @@ - + @@ -5287,17 +5311,18 @@ - + - + - + + @@ -5311,7 +5336,7 @@ - + @@ -5322,17 +5347,18 @@ - + - + - + + @@ -5342,7 +5368,7 @@ - + @@ -5351,7 +5377,7 @@ - + @@ -5359,12 +5385,13 @@ - + - + + @@ -5374,7 +5401,7 @@ - + @@ -5383,14 +5410,14 @@ - + - + @@ -5400,17 +5427,18 @@ - + - + - + + @@ -5429,13 +5457,13 @@ - + - + @@ -5445,23 +5473,24 @@ - + - + + - + @@ -5481,19 +5510,22 @@ - + - + - + + + @@ -5508,18 +5540,18 @@ - + - + - + @@ -5568,7 +5600,10 @@ - + + + + @@ -5584,7 +5619,7 @@ - + @@ -5619,7 +5654,9 @@ + + @@ -5639,7 +5676,9 @@ - + + + @@ -5658,6 +5697,7 @@ + @@ -5679,7 +5719,8 @@ - + + @@ -5704,7 +5745,7 @@ - + @@ -5713,7 +5754,7 @@ - + @@ -5721,11 +5762,13 @@ - + - + + + @@ -5738,12 +5781,13 @@ - + + @@ -5757,12 +5801,14 @@ - + + @@ -5821,6 +5867,8 @@ + diff --git a/libs/spandsp/src/Makefile.am b/libs/spandsp/src/Makefile.am index 090ddf0662..82704812e6 100644 --- a/libs/spandsp/src/Makefile.am +++ b/libs/spandsp/src/Makefile.am @@ -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: Makefile.am,v 1.100 2008/08/14 14:06:05 steveu Exp $ +## $Id: Makefile.am,v 1.101 2008/09/08 12:45:02 steveu Exp $ AM_CFLAGS = $(COMP_VENDOR_CFLAGS) AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS) @@ -120,6 +120,7 @@ nobase_include_HEADERS = spandsp/adsi.h \ spandsp/complex.h \ spandsp/complex_filters.h \ spandsp/complex_vector_float.h \ + spandsp/complex_vector_int.h \ spandsp/dc_restore.h \ spandsp/dds.h \ spandsp/dtmf.h \ diff --git a/libs/spandsp/src/adsi.c b/libs/spandsp/src/adsi.c index 75a5d4f1d0..0e587bad93 100644 --- a/libs/spandsp/src/adsi.c +++ b/libs/spandsp/src/adsi.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: adsi.c,v 1.59 2008/07/02 14:48:25 steveu Exp $ + * $Id: adsi.c,v 1.60 2008/09/07 12:45:16 steveu Exp $ */ /*! \file */ @@ -134,7 +134,7 @@ static int adsi_tx_get_bit(void *user_data) } else { - bit = PUTBIT_END_OF_DATA; + bit = SIG_STATUS_END_OF_DATA; if (s->tx_signal_on) { /* The FSK should now be switched off. */ @@ -176,7 +176,7 @@ static void adsi_rx_put_bit(void *user_data, int bit) /* Special conditions */ switch (bit) { - case PUTBIT_CARRIER_UP: + case SIG_STATUS_CARRIER_UP: span_log(&s->logging, SPAN_LOG_FLOW, "Carrier up.\n"); s->consecutive_ones = 0; s->bit_pos = 0; @@ -184,7 +184,7 @@ static void adsi_rx_put_bit(void *user_data, int bit) s->msg_len = 0; s->baudot_shift = 0; break; - case PUTBIT_CARRIER_DOWN: + case SIG_STATUS_CARRIER_DOWN: span_log(&s->logging, SPAN_LOG_FLOW, "Carrier down.\n"); break; default: @@ -297,18 +297,17 @@ static void adsi_tdd_put_async_byte(void *user_data, int byte) if (byte < 0) { /* Special conditions */ + printf("Status is %s (%d)\n", signal_status_to_str(byte), byte); switch (byte) { - case PUTBIT_CARRIER_UP: - span_log(&s->logging, SPAN_LOG_FLOW, "Carrier up.\n"); + case SIG_STATUS_CARRIER_UP: s->consecutive_ones = 0; s->bit_pos = 0; s->in_progress = 0; s->msg_len = 0; s->baudot_shift = 0; break; - case PUTBIT_CARRIER_DOWN: - span_log(&s->logging, SPAN_LOG_FLOW, "Carrier down.\n"); + case SIG_STATUS_CARRIER_DOWN: if (s->msg_len > 0) { /* Whatever we have to date constitutes the message */ diff --git a/libs/spandsp/src/async.c b/libs/spandsp/src/async.c index 2b6ddc2954..b57ece67cc 100644 --- a/libs/spandsp/src/async.c +++ b/libs/spandsp/src/async.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: async.c,v 1.11 2008/05/13 13:17:21 steveu Exp $ + * $Id: async.c,v 1.13 2008/09/07 12:45:16 steveu Exp $ */ /*! \file */ @@ -39,6 +39,37 @@ #include "spandsp/telephony.h" #include "spandsp/async.h" +const char *signal_status_to_str(int status) +{ + switch (status) + { + case SIG_STATUS_CARRIER_DOWN: + return "Carrier down"; + case SIG_STATUS_CARRIER_UP: + return "Carrier up"; + case SIG_STATUS_TRAINING_IN_PROGRESS: + return "Training in progress"; + case SIG_STATUS_TRAINING_SUCCEEDED: + return "Training succeeded"; + case SIG_STATUS_TRAINING_FAILED: + return "Training failed"; + case SIG_STATUS_FRAMING_OK: + return "Framing OK"; + case SIG_STATUS_END_OF_DATA: + return "End of data"; + case SIG_STATUS_ABORT: + return "Abort"; + case SIG_STATUS_BREAK: + return "Break"; + case SIG_STATUS_SHUTDOWN_COMPLETE: + return "Shutdown complete"; + case SIG_STATUS_OCTET_REPORT: + return "Octet report"; + } + return "???"; +} +/*- End of function --------------------------------------------------------*/ + async_rx_state_t *async_rx_init(async_rx_state_t *s, int data_bits, int parity, @@ -80,12 +111,12 @@ void async_rx_put_bit(void *user_data, int bit) /* Special conditions */ switch (bit) { - case PUTBIT_CARRIER_UP: - case PUTBIT_CARRIER_DOWN: - case PUTBIT_TRAINING_IN_PROGRESS: - case PUTBIT_TRAINING_SUCCEEDED: - case PUTBIT_TRAINING_FAILED: - case PUTBIT_END_OF_DATA: + case SIG_STATUS_CARRIER_UP: + case SIG_STATUS_CARRIER_DOWN: + case SIG_STATUS_TRAINING_IN_PROGRESS: + case SIG_STATUS_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_FAILED: + case SIG_STATUS_END_OF_DATA: s->put_byte(s->user_data, bit); s->bitpos = 0; s->byte_in_progress = 0; @@ -194,7 +225,7 @@ int async_tx_get_bit(void *user_data) if ((s->byte_in_progress = s->get_byte(s->user_data)) < 0) { /* No more data */ - bit = PUTBIT_END_OF_DATA; + bit = SIG_STATUS_END_OF_DATA; } else { diff --git a/libs/spandsp/src/bert.c b/libs/spandsp/src/bert.c index 63c3f51e29..c0e44752b5 100644 --- a/libs/spandsp/src/bert.c +++ b/libs/spandsp/src/bert.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: bert.c,v 1.27 2008/05/13 13:17:22 steveu Exp $ + * $Id: bert.c,v 1.28 2008/09/07 12:45:16 steveu Exp $ */ #if defined(HAVE_CONFIG_H) @@ -78,7 +78,7 @@ int bert_get_bit(bert_state_t *s) int bit; if (s->limit && s->tx_bits >= s->limit) - return PUTBIT_END_OF_DATA; + return SIG_STATUS_END_OF_DATA; bit = 0; switch (s->pattern_class) { @@ -185,27 +185,7 @@ void bert_put_bit(bert_state_t *s, int bit) if (bit < 0) { /* Special conditions */ - switch (bit) - { - case PUTBIT_TRAINING_IN_PROGRESS: - span_log(&s->logging, SPAN_LOG_FLOW, "Training in progress\n"); - break; - case PUTBIT_TRAINING_FAILED: - span_log(&s->logging, SPAN_LOG_FLOW, "Training failed\n"); - break; - case PUTBIT_TRAINING_SUCCEEDED: - span_log(&s->logging, SPAN_LOG_FLOW, "Training succeeded\n"); - break; - case PUTBIT_CARRIER_UP: - span_log(&s->logging, SPAN_LOG_FLOW, "Carrier up\n"); - break; - case PUTBIT_CARRIER_DOWN: - span_log(&s->logging, SPAN_LOG_FLOW, "Carrier down\n"); - break; - default: - span_log(&s->logging, SPAN_LOG_FLOW, "Eh!\n"); - break; - } + printf("Status is %s (%d)\n", signal_status_to_str(bit), bit); return; } bit = (bit & 1) ^ s->invert; diff --git a/libs/spandsp/src/dds_int.c b/libs/spandsp/src/dds_int.c index f832b5e105..e8a907ae1b 100644 --- a/libs/spandsp/src/dds_int.c +++ b/libs/spandsp/src/dds_int.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: dds_int.c,v 1.9 2008/07/02 14:48:25 steveu Exp $ + * $Id: dds_int.c,v 1.10 2008/09/01 16:07:33 steveu Exp $ */ /*! \file */ @@ -288,4 +288,58 @@ complexi_t dds_complexi_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, return amp; } /*- End of function --------------------------------------------------------*/ + +complexi16_t dds_lookup_complexi16(uint32_t phase) +{ + return complex_seti16(dds_lookup(phase + (1 << 30)), dds_lookup(phase)); +} +/*- End of function --------------------------------------------------------*/ + +complexi16_t dds_complexi16(uint32_t *phase_acc, int32_t phase_rate) +{ + complexi16_t amp; + + amp = complex_seti16(dds_lookup(*phase_acc + (1 << 30)), dds_lookup(*phase_acc)); + *phase_acc += phase_rate; + return amp; +} +/*- End of function --------------------------------------------------------*/ + +complexi16_t dds_complexi16_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase) +{ + complexi16_t amp; + + amp = complex_seti16((dds_lookup(*phase_acc + phase + (1 << 30))*scale) >> 15, + (dds_lookup(*phase_acc + phase)*scale) >> 15); + *phase_acc += phase_rate; + return amp; +} +/*- End of function --------------------------------------------------------*/ + +complexi32_t dds_lookup_complexi32(uint32_t phase) +{ + return complex_seti32(dds_lookup(phase + (1 << 30)), dds_lookup(phase)); +} +/*- End of function --------------------------------------------------------*/ + +complexi32_t dds_complexi32(uint32_t *phase_acc, int32_t phase_rate) +{ + complexi32_t amp; + + amp = complex_seti32(dds_lookup(*phase_acc + (1 << 30)), dds_lookup(*phase_acc)); + *phase_acc += phase_rate; + return amp; +} +/*- End of function --------------------------------------------------------*/ + +complexi32_t dds_complexi32_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase) +{ + complexi32_t amp; + + amp = complex_seti32((dds_lookup(*phase_acc + phase + (1 << 30))*scale) >> 15, + (dds_lookup(*phase_acc + phase)*scale) >> 15); + *phase_acc += phase_rate; + return amp; +} +/*- End of function --------------------------------------------------------*/ /*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/src/fsk.c b/libs/spandsp/src/fsk.c index 709bb333ef..fea13bc694 100644 --- a/libs/spandsp/src/fsk.c +++ b/libs/spandsp/src/fsk.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: fsk.c,v 1.44 2008/07/16 17:01:49 steveu Exp $ + * $Id: fsk.c,v 1.46 2008/09/07 12:45:16 steveu Exp $ */ /*! \file */ @@ -163,12 +163,12 @@ int fsk_tx(fsk_tx_state_t *s, int16_t *amp, int len) if ((s->baud_frac += s->baud_inc) >= SAMPLE_RATE*100) { s->baud_frac -= SAMPLE_RATE*100; - if ((bit = s->get_bit(s->get_bit_user_data)) == PUTBIT_END_OF_DATA) + if ((bit = s->get_bit(s->get_bit_user_data)) == SIG_STATUS_END_OF_DATA) { if (s->status_handler) - s->status_handler(s->status_user_data, MODEM_TX_STATUS_DATA_EXHAUSTED); + s->status_handler(s->status_user_data, SIG_STATUS_END_OF_DATA); if (s->status_handler) - s->status_handler(s->status_user_data, MODEM_TX_STATUS_SHUTDOWN_COMPLETE); + s->status_handler(s->status_user_data, SIG_STATUS_SHUTDOWN_COMPLETE); s->shutdown = TRUE; break; } @@ -329,7 +329,7 @@ int fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len) { /* Count down a short delay, to ensure we push the last few bits through the filters before stopping. */ - report_status_change(s, PUTBIT_CARRIER_DOWN); + report_status_change(s, SIG_STATUS_CARRIER_DOWN); continue; } } @@ -340,7 +340,7 @@ int fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len) if (power < s->carrier_on_power) continue; s->signal_present = 1; - report_status_change(s, PUTBIT_CARRIER_UP); + report_status_change(s, SIG_STATUS_CARRIER_UP); } /* Non-coherent FSK demodulation by correlation with the target tones over a one baud interval. The slow V.xx specs. are too open ended diff --git a/libs/spandsp/src/gsm0610_lpc.c b/libs/spandsp/src/gsm0610_lpc.c index 4f623bdbad..05e65a393a 100644 --- a/libs/spandsp/src/gsm0610_lpc.c +++ b/libs/spandsp/src/gsm0610_lpc.c @@ -25,7 +25,7 @@ * This code is based on the widely used GSM 06.10 code available from * http://kbs.cs.tu-berlin.de/~jutta/toast.html * - * $Id: gsm0610_lpc.c,v 1.20 2008/07/02 14:48:25 steveu Exp $ + * $Id: gsm0610_lpc.c,v 1.21 2008/09/04 14:40:05 steveu Exp $ */ /*! \file */ @@ -44,6 +44,7 @@ #include #endif #include +#include #include "spandsp/telephony.h" #include "spandsp/bitstream.h" diff --git a/libs/spandsp/src/hdlc.c b/libs/spandsp/src/hdlc.c index 439c57e0aa..1182b00068 100644 --- a/libs/spandsp/src/hdlc.c +++ b/libs/spandsp/src/hdlc.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: hdlc.c,v 1.60 2008/05/13 13:17:22 steveu Exp $ + * $Id: hdlc.c,v 1.61 2008/09/07 12:45:16 steveu Exp $ */ /*! \file */ @@ -47,8 +47,8 @@ static void rx_special_condition(hdlc_rx_state_t *s, int condition) /* Special conditions */ switch (condition) { - case PUTBIT_CARRIER_UP: - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_CARRIER_UP: + case SIG_STATUS_TRAINING_SUCCEEDED: /* Reset the HDLC receiver. */ s->raw_bit_stream = 0; s->len = 0; @@ -56,10 +56,10 @@ static void rx_special_condition(hdlc_rx_state_t *s, int condition) s->flags_seen = 0; s->framing_ok_announced = FALSE; /* Fall through */ - case PUTBIT_TRAINING_IN_PROGRESS: - case PUTBIT_TRAINING_FAILED: - case PUTBIT_CARRIER_DOWN: - case PUTBIT_END_OF_DATA: + case SIG_STATUS_TRAINING_IN_PROGRESS: + case SIG_STATUS_TRAINING_FAILED: + case SIG_STATUS_CARRIER_DOWN: + case SIG_STATUS_END_OF_DATA: s->frame_handler(s->user_data, NULL, condition, TRUE); break; default: @@ -81,7 +81,7 @@ static __inline__ void octet_set_and_count(hdlc_rx_state_t *s) if (--s->octet_count <= 0) { s->octet_count = s->octet_count_report_interval; - s->frame_handler(s->user_data, NULL, PUTBIT_OCTET_REPORT, TRUE); + s->frame_handler(s->user_data, NULL, SIG_STATUS_OCTET_REPORT, TRUE); } } else @@ -104,7 +104,7 @@ static __inline__ void octet_count(hdlc_rx_state_t *s) if (--s->octet_count <= 0) { s->octet_count = s->octet_count_report_interval; - s->frame_handler(s->user_data, NULL, PUTBIT_OCTET_REPORT, TRUE); + s->frame_handler(s->user_data, NULL, SIG_STATUS_OCTET_REPORT, TRUE); } } } @@ -116,7 +116,7 @@ static void rx_flag_or_abort(hdlc_rx_state_t *s) { /* Hit HDLC abort */ s->rx_aborts++; - s->frame_handler(s->user_data, NULL, PUTBIT_ABORT, TRUE); + s->frame_handler(s->user_data, NULL, SIG_STATUS_ABORT, TRUE); /* If we have not yet seen enough flags, restart the count. If we are beyond that point, just back off one step, so we need to see another flag before proceeding to collect frame octets. */ @@ -184,7 +184,7 @@ static void rx_flag_or_abort(hdlc_rx_state_t *s) s->flags_seen = 0; if (++s->flags_seen >= s->framing_ok_threshold && !s->framing_ok_announced) { - s->frame_handler(s->user_data, NULL, PUTBIT_FRAMING_OK, TRUE); + s->frame_handler(s->user_data, NULL, SIG_STATUS_FRAMING_OK, TRUE); s->framing_ok_announced = TRUE; } } @@ -493,7 +493,7 @@ int hdlc_tx_get_byte(hdlc_tx_state_t *s) if (s->tx_end) { s->tx_end = FALSE; - return PUTBIT_END_OF_DATA; + return SIG_STATUS_END_OF_DATA; } return s->idle_octet; } @@ -522,7 +522,7 @@ int hdlc_tx_get(hdlc_tx_state_t *s, uint8_t buf[], size_t max_len) for (i = 0; i < max_len; i++) { - if ((x = hdlc_tx_get_byte(s)) == PUTBIT_END_OF_DATA) + if ((x = hdlc_tx_get_byte(s)) == SIG_STATUS_END_OF_DATA) return i; buf[i] = x; } diff --git a/libs/spandsp/src/libspandsp.dsp b/libs/spandsp/src/libspandsp.dsp index ec66ac7e2b..cc031e142b 100644 --- a/libs/spandsp/src/libspandsp.dsp +++ b/libs/spandsp/src/libspandsp.dsp @@ -459,6 +459,10 @@ SOURCE=.\spandsp/complex_vector_float.h # End Source File # Begin Source File +SOURCE=.\spandsp/complex_vector_int.h +# End Source File +# Begin Source File + SOURCE=.\spandsp/dc_restore.h # End Source File # Begin Source File diff --git a/libs/spandsp/src/modem_connect_tones.c b/libs/spandsp/src/modem_connect_tones.c index 4178230812..98e84a5599 100644 --- a/libs/spandsp/src/modem_connect_tones.c +++ b/libs/spandsp/src/modem_connect_tones.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: modem_connect_tones.c,v 1.27 2008/08/13 14:55:51 steveu Exp $ + * $Id: modem_connect_tones.c,v 1.28 2008/09/07 12:45:16 steveu Exp $ */ /*! \file */ @@ -284,12 +284,12 @@ static void v21_put_bit(void *user_data, int bit) /* Special conditions. */ switch (bit) { - case PUTBIT_CARRIER_DOWN: + case SIG_STATUS_CARRIER_DOWN: /* Only declare tone off, if we were the one to declare tone on. */ if (s->tone_present == MODEM_CONNECT_TONES_FAX_PREAMBLE) report_tone_state(s, MODEM_CONNECT_TONES_NONE, -99); /* Fall through */ - case PUTBIT_CARRIER_UP: + case SIG_STATUS_CARRIER_UP: s->raw_bit_stream = 0; s->num_bits = 0; s->flags_seen = 0; diff --git a/libs/spandsp/src/queue.c b/libs/spandsp/src/queue.c index 8f70a2e479..35fe6551f7 100644 --- a/libs/spandsp/src/queue.c +++ b/libs/spandsp/src/queue.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: queue.c,v 1.22 2008/05/15 14:26:30 steveu Exp $ + * $Id: queue.c,v 1.23 2008/09/09 16:25:51 steveu Exp $ */ /*! \file */ @@ -39,6 +39,7 @@ #include #include +#define FULLY_DEFINE_QUEUE_STATE_T #include "spandsp/queue.h" int queue_empty(queue_state_t *s) diff --git a/libs/spandsp/src/silence_gen.c b/libs/spandsp/src/silence_gen.c index 42d6c29e0e..d638b5f5d0 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.14 2008/07/26 04:53:00 steveu Exp $ + * $Id: silence_gen.c,v 1.16 2008/09/07 12:45:16 steveu Exp $ */ /*! \file */ @@ -59,7 +59,7 @@ int silence_gen(silence_gen_state_t *s, int16_t *amp, int max_len) { max_len = s->remaining_samples; if (max_len && s->status_handler) - s->status_handler(s->status_user_data, MODEM_TX_STATUS_SHUTDOWN_COMPLETE); + s->status_handler(s->status_user_data, SIG_STATUS_SHUTDOWN_COMPLETE); } s->remaining_samples -= max_len; } diff --git a/libs/spandsp/src/spandsp.h.in b/libs/spandsp/src/spandsp.h.in index c27c8c5148..c59f68382c 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.9 2008/08/14 14:06:05 steveu Exp $ + * $Id: spandsp.h.in,v 1.10 2008/09/01 16:07:34 steveu Exp $ */ /*! \file */ @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include diff --git a/libs/spandsp/src/spandsp/async.h b/libs/spandsp/src/spandsp/async.h index 083b83278e..23fba25784 100644 --- a/libs/spandsp/src/spandsp/async.h +++ b/libs/spandsp/src/spandsp/async.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: async.h,v 1.16 2008/07/17 14:27:11 steveu Exp $ + * $Id: async.h,v 1.18 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -49,42 +49,36 @@ and decoding must occur before data is fed to this module. #if !defined(_SPANDSP_ASYNC_H_) #define _SPANDSP_ASYNC_H_ -/*! Special "bit" values for the put and get bit functions */ +/*! Special "bit" values for the bitstream put and get functions, and the signal status functions. */ enum { /*! \brief The carrier signal has dropped. */ - PUTBIT_CARRIER_DOWN = -1, + SIG_STATUS_CARRIER_DOWN = -1, /*! \brief The carrier signal is up. This merely indicates that carrier energy has been seen. It is not an indication that the carrier is either valid, or of the expected type. */ - PUTBIT_CARRIER_UP = -2, + SIG_STATUS_CARRIER_UP = -2, /*! \brief The modem is training. This is an early indication that the signal seems to be of the right type. This may be needed in time critical applications, like T.38, to forward an early indication of what is happening on the wire. */ - PUTBIT_TRAINING_IN_PROGRESS = -3, + SIG_STATUS_TRAINING_IN_PROGRESS = -3, /*! \brief The modem has trained, and is ready for data exchange. */ - PUTBIT_TRAINING_SUCCEEDED = -4, + SIG_STATUS_TRAINING_SUCCEEDED = -4, /*! \brief The modem has failed to train. */ - PUTBIT_TRAINING_FAILED = -5, + SIG_STATUS_TRAINING_FAILED = -5, /*! \brief Packet framing (e.g. HDLC framing) is OK. */ - PUTBIT_FRAMING_OK = -6, + SIG_STATUS_FRAMING_OK = -6, /*! \brief The data stream has ended. */ - PUTBIT_END_OF_DATA = -7, + SIG_STATUS_END_OF_DATA = -7, /*! \brief An abort signal (e.g. an HDLC abort) has been received. */ - PUTBIT_ABORT = -8, + SIG_STATUS_ABORT = -8, /*! \brief A break signal (e.g. an async break) has been received. */ - PUTBIT_BREAK = -9, + SIG_STATUS_BREAK = -9, + /*! \brief A modem has completed its task, and shut down. */ + SIG_STATUS_SHUTDOWN_COMPLETE = -10, /*! \brief Regular octet report for things like HDLC to the MTP standards. */ - PUTBIT_OCTET_REPORT = -10 -}; - -enum -{ - /*! \brief The data source for a transmitter is exhausted. */ - MODEM_TX_STATUS_DATA_EXHAUSTED = -1, - /*! \brief The transmitter has completed its task, and shut down. */ - MODEM_TX_STATUS_SHUTDOWN_COMPLETE = -2 + SIG_STATUS_OCTET_REPORT = -11 }; /*! Message put function for data pumps */ @@ -185,6 +179,12 @@ extern "C" { #endif +/*! Convert a signal status to a short text description. + \brief Convert a signal status to a short text description. + \param status The modem signal status. + \return A pointer to the description. */ +const char *signal_status_to_str(int status); + /*! Initialise an asynchronous data transmit context. \brief Initialise an asynchronous data transmit context. \param s The transmitter context. @@ -231,11 +231,11 @@ async_rx_state_t *async_rx_init(async_rx_state_t *s, \brief Accept a bit from a received serial bit stream \param user_data An opaque point which must point to a receiver context. \param bit The new bit. Some special values are supported for this field. - - PUTBIT_CARRIER_UP - - PUTBIT_CARRIER_DOWN - - PUTBIT_TRAINING_SUCCEEDED - - PUTBIT_TRAINING_FAILED - - PUTBIT_END_OF_DATA */ + - SIG_STATUS_CARRIER_UP + - SIG_STATUS_CARRIER_DOWN + - SIG_STATUS_TRAINING_SUCCEEDED + - SIG_STATUS_TRAINING_FAILED + - SIG_STATUS_END_OF_DATA */ void async_rx_put_bit(void *user_data, int bit); #if defined(__cplusplus) diff --git a/libs/spandsp/src/spandsp/complex.h b/libs/spandsp/src/spandsp/complex.h index 1281d7082f..c33d6fb90a 100644 --- a/libs/spandsp/src/spandsp/complex.h +++ b/libs/spandsp/src/spandsp/complex.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: complex.h,v 1.16 2008/04/17 14:27:00 steveu Exp $ + * $Id: complex.h,v 1.18 2008/09/03 13:41:42 steveu Exp $ */ /*! \file */ @@ -329,6 +329,56 @@ static __inline__ complexl_t complex_mull(const complexl_t *x, const complexl_t /*- End of function --------------------------------------------------------*/ #endif +static __inline__ complexi_t complex_muli(const complexi_t *x, const complexi_t *y) +{ + complexi_t z; + + z.re = x->re*y->re - x->im*y->im; + z.im = x->re*y->im + x->im*y->re; + return z; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ complexi16_t complex_muli16(const complexi16_t *x, const complexi16_t *y) +{ + complexi16_t z; + + z.re = (int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im; + z.im = (int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re; + return z; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ complexi16_t complex_mul_q1_15(const complexi16_t *x, const complexi16_t *y) +{ + complexi16_t z; + + z.re = ((int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im) >> 15; + z.im = ((int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re) >> 15; + return z; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ complexi32_t complex_muli32i16(const complexi32_t *x, const complexi16_t *y) +{ + complexi32_t z; + + z.re = x->re*(int32_t) y->re - x->im*(int32_t) y->im; + z.im = x->re*(int32_t) y->im + x->im*(int32_t) y->re; + return z; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ complexi32_t complex_muli32(const complexi32_t *x, const complexi32_t *y) +{ + complexi32_t z; + + z.re = x->re*y->re - x->im*y->im; + z.im = x->re*y->im + x->im*y->re; + return z; +} +/*- End of function --------------------------------------------------------*/ + static __inline__ complexf_t complex_divf(const complexf_t *x, const complexf_t *y) { complexf_t z; @@ -399,7 +449,7 @@ static __inline__ complexl_t complex_conjl(const complexl_t *x) /*- End of function --------------------------------------------------------*/ #endif -static __inline__ complexi_t complexi_conj(const complexi_t *x) +static __inline__ complexi_t complex_conji(const complexi_t *x) { complexi_t z; @@ -409,6 +459,26 @@ static __inline__ complexi_t complexi_conj(const complexi_t *x) } /*- End of function --------------------------------------------------------*/ +static __inline__ complexi16_t complex_conji16(const complexi16_t *x) +{ + complexi16_t z; + + z.re = x->re; + z.im = -x->im; + return z; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ complexi32_t complex_conji32(const complexi32_t *x) +{ + complexi32_t z; + + z.re = x->re; + z.im = -x->im; + return z; +} +/*- End of function --------------------------------------------------------*/ + static __inline__ float powerf(const complexf_t *x) { return x->re*x->re + x->im*x->im; diff --git a/libs/spandsp/src/spandsp/complex_vector_int.h b/libs/spandsp/src/spandsp/complex_vector_int.h new file mode 100644 index 0000000000..278b9296ae --- /dev/null +++ b/libs/spandsp/src/spandsp/complex_vector_int.h @@ -0,0 +1,104 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * complex_vector_int.h + * + * Written by Steve Underwood + * + * Copyright (C) 2003 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: complex_vector_int.h,v 1.1 2008/09/01 16:07:34 steveu Exp $ + */ + +#if !defined(_SPANDSP_COMPLEX_VECTOR_INT_H_) +#define _SPANDSP_COMPLEX_VECTOR_INT_H_ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +static __inline__ void cvec_copyi(complexi_t z[], const complexi_t x[], int n) +{ + memcpy(z, x, n*sizeof(z[0])); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void cvec_copyi16(complexi16_t z[], const complexi16_t x[], int n) +{ + memcpy(z, x, n*sizeof(z[0])); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void cvec_copyi32(complexi32_t z[], const complexi32_t x[], int n) +{ + memcpy(z, x, n*sizeof(z[0])); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void cvec_zeroi(complexi_t z[], int n) +{ + memset(z, 0, n*sizeof(z[0])); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void cvec_zeroi16(complexi16_t z[], int n) +{ + memset(z, 0, n*sizeof(z[0])); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void cvec_zeroi32(complexi32_t z[], int n) +{ + memset(z, 0, n*sizeof(z[0])); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void cvec_seti(complexi_t z[], complexi_t *x, int n) +{ + int i; + + for (i = 0; i < n; i++) + z[i] = *x; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void cvec_seti16(complexi16_t z[], complexi16_t *x, int n) +{ + int i; + + for (i = 0; i < n; i++) + z[i] = *x; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void cvec_seti32(complexi32_t z[], complexi32_t *x, int n) +{ + int i; + + for (i = 0; i < n; i++) + z[i] = *x; +} +/*- End of function --------------------------------------------------------*/ + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/src/spandsp/dds.h b/libs/spandsp/src/spandsp/dds.h index fffa704b67..6dfd999143 100644 --- a/libs/spandsp/src/spandsp/dds.h +++ b/libs/spandsp/src/spandsp/dds.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: dds.h,v 1.18 2008/04/17 14:27:00 steveu Exp $ + * $Id: dds.h,v 1.20 2008/09/04 14:40:05 steveu Exp $ */ /*! \file */ @@ -100,6 +100,12 @@ int16_t dds_lookup(uint32_t phase); */ int16_t dds_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase); +/*! \brief Lookup the complex integer value of a specified phase. + \param phase The phase accumulator value to be looked up. + \return The complex signal amplitude, between (-32767, -32767) and (32767, 32767). +*/ +complexi_t dds_lookup_complexi(uint32_t phase); + /*! \brief Generate a complex integer tone sample. \param phase_acc A pointer to a phase accumulator value. \param phase_rate The phase increment to be applied. @@ -107,12 +113,6 @@ int16_t dds_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phas */ complexi_t dds_complexi(uint32_t *phase_acc, int32_t phase_rate); -/*! \brief Lookup the complex integer value of a specified phase. - \param phase The phase accumulator value to be looked up. - \return The complex signal amplitude, between (-32767, -32767) and (32767, 32767). -*/ -complexi_t dds_lookup_complexi(uint32_t phase); - /*! \brief Generate a complex integer tone sample, with modulation. \param phase_acc A pointer to a phase accumulator value. \param phase_rate The phase increment to be applied. @@ -122,6 +122,61 @@ complexi_t dds_lookup_complexi(uint32_t phase); */ complexi_t dds_complexi_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase); +/*! \brief Generate a complex 16 bit integer tone sample. + \param phase_acc A pointer to a phase accumulator value. + \param phase_rate The phase increment to be applied. + \return The complex signal amplitude, between (-32767, -32767) and (32767, 32767). +*/ +complexi16_t dds_lookup_complexi16(uint32_t phase); + +/*! \brief Generate a complex 16 bit integer tone sample. + \param phase_acc A pointer to a phase accumulator value. + \param phase_rate The phase increment to be applied. + \return The complex signal amplitude, between (-32767, -32767) and (32767, 32767). +*/ +complexi16_t dds_complexi16(uint32_t *phase_acc, int32_t phase_rate); + +/*! \brief Generate a complex 16bit integer tone sample, with modulation. + \param phase_acc A pointer to a phase accumulator value. + \param phase_rate The phase increment to be applied. + \param scale The scaling factor. + \param phase The phase offset. + \return The complex signal amplitude, between (-32767, -32767) and (32767, 32767). +*/ +complexi16_t dds_complexi16_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase); + +/*! \brief Generate a complex 32 bit integer tone sample, with modulation. + \param phase_acc A pointer to a phase accumulator value. + \param phase_rate The phase increment to be applied. + \param scale The scaling factor. + \param phase The phase offset. + \return The complex signal amplitude, between (-32767, -32767) and (32767, 32767). +*/ +complexi32_t dds_complexi32_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase); + +/*! \brief Generate a complex 32 bit integer tone sample. + \param phase_acc A pointer to a phase accumulator value. + \param phase_rate The phase increment to be applied. + \return The complex signal amplitude, between (-32767, -32767) and (32767, 32767). +*/ +complexi32_t dds_lookup_complexi32(uint32_t phase); + +/*! \brief Generate a complex 32 bit integer tone sample. + \param phase_acc A pointer to a phase accumulator value. + \param phase_rate The phase increment to be applied. + \return The complex signal amplitude, between (-32767, -32767) and (32767, 32767). +*/ +complexi32_t dds_complexi32(uint32_t *phase_acc, int32_t phase_rate); + +/*! \brief Generate a complex 32 bit integer tone sample, with modulation. + \param phase_acc A pointer to a phase accumulator value. + \param phase_rate The phase increment to be applied. + \param scale The scaling factor. + \param phase The phase offset. + \return The complex signal amplitude, between (-32767, -32767) and (32767, 32767). +*/ +complexi32_t dds_complexi32_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase); + /*! \brief Find the phase rate equivalent to a frequency, in Hz. \param frequency The frequency, in Hz. \return The equivalent phase rate. diff --git a/libs/spandsp/src/spandsp/echo.h b/libs/spandsp/src/spandsp/echo.h index 38c7f74a75..6f48a93abb 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.15 2008/08/29 10:02:47 steveu Exp $ + * $Id: echo.h,v 1.16 2008/09/04 14:40:05 steveu Exp $ */ /*! \file */ @@ -126,7 +126,7 @@ enum ECHO_CAN_USE_SUPPRESSOR = 0x10, ECHO_CAN_USE_TX_HPF = 0x20, ECHO_CAN_USE_RX_HPF = 0x40, - ECHO_CAN_DISABLE = 0x80, + ECHO_CAN_DISABLE = 0x80 }; /*! diff --git a/libs/spandsp/src/spandsp/fsk.h b/libs/spandsp/src/spandsp/fsk.h index ae25ab28ff..ac17c3121a 100644 --- a/libs/spandsp/src/spandsp/fsk.h +++ b/libs/spandsp/src/spandsp/fsk.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: fsk.h,v 1.30 2008/07/16 14:23:48 steveu Exp $ + * $Id: fsk.h,v 1.31 2008/09/04 14:40:05 steveu Exp $ */ /*! \file */ @@ -111,7 +111,7 @@ enum FSK_BELL103CH1, FSK_BELL103CH2, FSK_BELL202, - FSK_WEITBRECHT, /* Used for TDD (Telecom Device for the Deaf) */ + FSK_WEITBRECHT /* Used for TDD (Telecom Device for the Deaf) */ }; extern const fsk_spec_t preset_fsk_specs[]; diff --git a/libs/spandsp/src/spandsp/queue.h b/libs/spandsp/src/spandsp/queue.h index 86b8a8fb52..bc3f22b301 100644 --- a/libs/spandsp/src/spandsp/queue.h +++ b/libs/spandsp/src/spandsp/queue.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: queue.h,v 1.16 2008/05/30 13:51:28 steveu Exp $ + * $Id: queue.h,v 1.17 2008/09/09 16:25:51 steveu Exp $ */ /*! \file */ @@ -63,8 +63,10 @@ typedef struct volatile int iptr; /*! \brief The buffer output pointer. */ volatile int optr; +#if defined(FULLY_DEFINE_QUEUE_STATE_T) /*! \brief The data buffer, sized at the time the structure is created. */ uint8_t data[]; +#endif } queue_state_t; #define QUEUE_STATE_T_SIZE(len) (sizeof(queue_state_t) + len + 1) diff --git a/libs/spandsp/src/spandsp/t30.h b/libs/spandsp/src/spandsp/t30.h index 8f2af0145d..b744bcc586 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.114 2008/08/13 00:11:30 steveu Exp $ + * $Id: t30.h,v 1.115 2008/09/04 14:40:05 steveu Exp $ */ /*! \file */ @@ -338,7 +338,7 @@ enum T30_SUPPORT_V29 = 0x02, T30_SUPPORT_V17 = 0x04, T30_SUPPORT_V34 = 0x08, - T30_SUPPORT_IAF = 0x10, + T30_SUPPORT_IAF = 0x10 }; enum diff --git a/libs/spandsp/src/spandsp/t38_core.h b/libs/spandsp/src/spandsp/t38_core.h index 27d05233b5..d7ef1d00fa 100644 --- a/libs/spandsp/src/spandsp/t38_core.h +++ b/libs/spandsp/src/spandsp/t38_core.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: t38_core.h,v 1.28 2008/06/19 13:27:45 steveu Exp $ + * $Id: t38_core.h,v 1.29 2008/09/04 14:40:05 steveu Exp $ */ /*! \file */ @@ -142,7 +142,7 @@ enum t38_field_classes_e { T38_FIELD_CLASS_NONE = 0, T38_FIELD_CLASS_HDLC, - T38_FIELD_CLASS_NON_ECM, + T38_FIELD_CLASS_NON_ECM }; /*! T.38 message types */ diff --git a/libs/spandsp/src/spandsp/t38_gateway.h b/libs/spandsp/src/spandsp/t38_gateway.h index d414916766..0ad75468ac 100644 --- a/libs/spandsp/src/spandsp/t38_gateway.h +++ b/libs/spandsp/src/spandsp/t38_gateway.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: t38_gateway.h,v 1.56 2008/08/14 14:06:05 steveu Exp $ + * $Id: t38_gateway.h,v 1.57 2008/09/02 13:56:10 steveu Exp $ */ /*! \file */ @@ -125,6 +125,21 @@ typedef struct typedef struct { + /*! \brief HDLC message buffers. */ + uint8_t buf[T38_MAX_HDLC_LEN]; + /*! \brief HDLC message lengths. */ + int len; + /*! \brief HDLC message status flags. */ + int flags; + /*! \brief HDLC buffer contents. */ + int contents; +} t38_gateway_hdlc_buf_t; + +typedef struct +{ + /*! \brief HDLC message buffers. */ + t38_gateway_hdlc_buf_t buf[T38_TX_HDLC_BUFS]; +#if 0 /*! \brief HDLC message buffers. */ uint8_t buf[T38_TX_HDLC_BUFS][T38_MAX_HDLC_LEN]; /*! \brief HDLC message lengths. */ @@ -133,6 +148,7 @@ typedef struct int flags[T38_TX_HDLC_BUFS]; /*! \brief HDLC buffer contents. */ int contents[T38_TX_HDLC_BUFS]; +#endif /*! \brief HDLC buffer number for input. */ int in; /*! \brief HDLC buffer number for output. */ diff --git a/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h b/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h index 4d6fac6451..1943ee9199 100644 --- a/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h +++ b/libs/spandsp/src/spandsp/t38_non_ecm_buffer.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: t38_non_ecm_buffer.h,v 1.1 2008/08/14 14:06:05 steveu Exp $ + * $Id: t38_non_ecm_buffer.h,v 1.2 2008/09/02 13:56:10 steveu Exp $ */ /*! \file */ @@ -83,10 +83,13 @@ typedef struct /*! \brief The number of octets input to the buffer. */ int in_octets; - /*! \brief The number of octets output from the buffer. */ - int out_octets; /*! \brief The number of rows input to the buffer. */ int in_rows; + /*! \brief The number of non-ECM fill octets generated for minimum row bits + purposes. */ + int min_row_bits_fill_octets; + /*! \brief The number of octets output from the buffer. */ + int out_octets; /*! \brief The number of rows output from the buffer. */ int out_rows; /*! \brief The number of non-ECM fill octets generated for flow control @@ -106,6 +109,12 @@ extern "C" \return A pointer to the buffer context, or NULL if there was a problem. */ t38_non_ecm_buffer_state_t *t38_non_ecm_buffer_init(t38_non_ecm_buffer_state_t *s, int mode, int min_row_bits); +/*! \brief Set the mode of a T.38 rate adapting non-ECM buffer context. + \param s The buffer context. + \param mode TRUE for image data mode, or FALSE for TCF mode. + \param bits The minimum number of bits per FAX image row. */ +void t38_non_ecm_buffer_set_mode(t38_non_ecm_buffer_state_t *s, int mode, int min_row_bits); + /*! \brief Inject data to T.38 rate adapting non-ECM buffer context. \param s The buffer context. \param buf The data buffer to be injected. @@ -117,11 +126,17 @@ void t38_non_ecm_buffer_inject(t38_non_ecm_buffer_state_t *s, const uint8_t *buf \param s The buffer context. */ void t38_non_ecm_buffer_push(t38_non_ecm_buffer_state_t *s); -/*! \brief Report the status of a T.38 rate adapting non-ECM buffer context to the specified +/*! \brief Report the input status of a T.38 rate adapting non-ECM buffer context to the specified logging context. \param s The buffer context. \param logging The logging context. */ -void t38_non_ecm_buffer_report_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging); +void t38_non_ecm_buffer_report_input_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging); + +/*! \brief Report the output status of a T.38 rate adapting non-ECM buffer context to the specified + logging context. + \param s The buffer context. + \param logging The logging context. */ +void t38_non_ecm_buffer_report_output_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging); /*! \brief Get the next bit of data from a T.38 rate adapting non-ECM buffer context. \param user_data The buffer context, cast to a void pointer. diff --git a/libs/spandsp/src/spandsp/v17rx.h b/libs/spandsp/src/spandsp/v17rx.h index a5240ee9ac..c36de7ff28 100644 --- a/libs/spandsp/src/spandsp/v17rx.h +++ b/libs/spandsp/src/spandsp/v17rx.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: v17rx.h,v 1.52 2008/07/16 14:23:48 steveu Exp $ + * $Id: v17rx.h,v 1.53 2008/09/08 12:54:32 steveu Exp $ */ /*! \file */ @@ -306,28 +306,26 @@ typedef struct /*! \brief The previous value of agc_scaling, needed to reuse old training. */ float agc_scaling_save; - /*! \brief The current delta factor for updating the equalizer coefficients. */ - float eq_delta; -#if defined(SPANDSP_USE_FIXED_POINTx) - /*! \brief The adaptive equalizer coefficients. */ - complexi_t eq_coeff[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN]; - /*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */ - complexi_t eq_coeff_save[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN]; - /*! \brief The equalizer signal buffer. */ - complexi_t eq_buf[V17_EQUALIZER_MASK + 1]; -#else - complexf_t eq_coeff[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN]; - complexf_t eq_coeff_save[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN]; - complexf_t eq_buf[V17_EQUALIZER_MASK + 1]; -#endif /*! \brief Current read offset into the equalizer buffer. */ int eq_step; /*! \brief Current write offset into the equalizer buffer. */ int eq_put_step; + /*! \brief Symbol counter to the next equalizer update. */ + int eq_skip; /*! \brief The current half of the baud. */ int baud_half; + #if defined(SPANDSP_USE_FIXED_POINTx) + /*! \brief The current delta factor for updating the equalizer coefficients. */ + float eq_delta; + /*! \brief The adaptive equalizer coefficients. */ + complexi16_t eq_coeff[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN]; + /*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */ + complexi16_t eq_coeff_save[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN]; + /*! \brief The equalizer signal buffer. */ + complexi16_t eq_buf[V17_EQUALIZER_MASK + 1]; + /*! Low band edge filter for symbol sync. */ int32_t symbol_sync_low[2]; /*! High band edge filter for symbol sync. */ @@ -337,6 +335,15 @@ typedef struct /*! Baud phase for symbol sync. */ int32_t baud_phase; #else + /*! \brief The current delta factor for updating the equalizer coefficients. */ + float eq_delta; + /*! \brief The adaptive equalizer coefficients. */ + complexf_t eq_coeff[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN]; + /*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */ + complexf_t eq_coeff_save[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN]; + /*! \brief The equalizer signal buffer. */ + complexf_t eq_buf[V17_EQUALIZER_MASK + 1]; + /*! Low band edge filter for symbol sync. */ float symbol_sync_low[2]; /*! High band edge filter for symbol sync. */ @@ -346,6 +353,7 @@ typedef struct /*! Baud phase for symbol sync. */ float baud_phase; #endif + /*! \brief The total symbol timing correction since the carrier came up. This is only for performance analysis purposes. */ int total_baud_timing_correction; diff --git a/libs/spandsp/src/spandsp/v27ter_rx.h b/libs/spandsp/src/spandsp/v27ter_rx.h index d068a58761..acd64fd452 100644 --- a/libs/spandsp/src/spandsp/v27ter_rx.h +++ b/libs/spandsp/src/spandsp/v27ter_rx.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: v27ter_rx.h,v 1.47 2008/07/16 14:23:48 steveu Exp $ + * $Id: v27ter_rx.h,v 1.48 2008/09/08 12:54:32 steveu Exp $ */ /*! \file */ @@ -144,22 +144,10 @@ typedef struct /*! \brief The previous value of agc_scaling, needed to reuse old training. */ float agc_scaling_save; + /*! \brief The position of the current symbol in the constellation, used for + differential decoding. */ int constellation_state; - /*! \brief The current delta factor for updating the equalizer coefficients. */ - float eq_delta; -#if defined(SPANDSP_USE_FIXED_POINTx) - /*! \brief The adaptive equalizer coefficients. */ - complexi_t eq_coeff[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN]; - /*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */ - complexi_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN]; - /*! \brief The equalizer signal buffer. */ - complexi_t eq_buf[V27TER_EQUALIZER_MASK + 1]; -#else - complexf_t eq_coeff[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN]; - complexf_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN]; - complexf_t eq_buf[V27TER_EQUALIZER_MASK + 1]; -#endif /*! \brief Current offset into the equalizer buffer. */ int eq_step; /*! \brief Current write offset into the equalizer buffer. */ @@ -167,6 +155,29 @@ typedef struct /*! \brief Symbol counter to the next equalizer update. */ int eq_skip; + /*! \brief The current half of the baud. */ + int baud_half; + +#if defined(SPANDSP_USE_FIXED_POINTx) + /*! \brief The current delta factor for updating the equalizer coefficients. */ + float eq_delta; + /*! \brief The adaptive equalizer coefficients. */ + complexi16_t eq_coeff[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN]; + /*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */ + complexi16_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN]; + /*! \brief The equalizer signal buffer. */ + complexi16_t eq_buf[V27TER_EQUALIZER_MASK + 1]; +#else + /*! \brief The current delta factor for updating the equalizer coefficients. */ + float eq_delta; + /*! \brief The adaptive equalizer coefficients. */ + complexf_t eq_coeff[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN]; + /*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */ + complexf_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN]; + /*! \brief The equalizer signal buffer. */ + complexf_t eq_buf[V27TER_EQUALIZER_MASK + 1]; +#endif + /*! \brief Integration variable for damping the Gardner algorithm tests. */ int gardner_integrate; /*! \brief Current step size of Gardner algorithm integration. */ @@ -174,8 +185,6 @@ typedef struct /*! \brief The total symbol timing correction since the carrier came up. This is only for performance analysis purposes. */ int total_baud_timing_correction; - /*! \brief The current fractional phase of the baud timing. */ - int baud_phase; /*! \brief Starting phase angles for the coarse carrier aquisition step. */ int32_t start_angles[2]; diff --git a/libs/spandsp/src/spandsp/v29rx.h b/libs/spandsp/src/spandsp/v29rx.h index bf8742ac63..ac85d7bebc 100644 --- a/libs/spandsp/src/spandsp/v29rx.h +++ b/libs/spandsp/src/spandsp/v29rx.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: v29rx.h,v 1.55 2008/07/16 14:23:48 steveu Exp $ + * $Id: v29rx.h,v 1.59 2008/09/08 12:45:02 steveu Exp $ */ /*! \file */ @@ -212,22 +212,10 @@ typedef struct /*! \brief The previous value of agc_scaling, needed to reuse old training. */ float agc_scaling_save; + /*! \brief The position of the current symbol in the constellation, used for + differential decoding. */ int constellation_state; - /*! \brief The current delta factor for updating the equalizer coefficients. */ - float eq_delta; -#if defined(SPANDSP_USE_FIXED_POINTx) - /*! \brief The adaptive equalizer coefficients. */ - complexi_t eq_coeff[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN]; - /*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */ - complexi_t eq_coeff_save[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN]; - /*! \brief The equalizer signal buffer. */ - complexi_t eq_buf[V29_EQUALIZER_MASK + 1]; -#else - complexf_t eq_coeff[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN]; - complexf_t eq_coeff_save[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN]; - complexf_t eq_buf[V29_EQUALIZER_MASK + 1]; -#endif /*! \brief Current offset into the equalizer buffer. */ int eq_step; /*! \brief Current write offset into the equalizer buffer. */ @@ -237,7 +225,17 @@ typedef struct /*! \brief The current half of the baud. */ int baud_half; -#if defined(SPANDSP_USE_FIXED_POINTx) + +#if defined(SPANDSP_USE_FIXED_POINT) + /*! \brief The current delta factor for updating the equalizer coefficients. */ + int16_t eq_delta; + /*! \brief The adaptive equalizer coefficients. */ + complexi16_t eq_coeff[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN]; + /*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */ + complexi16_t eq_coeff_save[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN]; + /*! \brief The equalizer signal buffer. */ + complexi16_t eq_buf[V29_EQUALIZER_MASK + 1]; + /*! Low band edge filter for symbol sync. */ int32_t symbol_sync_low[2]; /*! High band edge filter for symbol sync. */ @@ -247,6 +245,15 @@ typedef struct /*! Baud phase for symbol sync. */ int32_t baud_phase; #else + /*! \brief The current delta factor for updating the equalizer coefficients. */ + float eq_delta; + /*! \brief The adaptive equalizer coefficients. */ + complexf_t eq_coeff[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN]; + /*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */ + complexf_t eq_coeff_save[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN]; + /*! \brief The equalizer signal buffer. */ + complexf_t eq_buf[V29_EQUALIZER_MASK + 1]; + /*! Low band edge filter for symbol sync. */ float symbol_sync_low[2]; /*! High band edge filter for symbol sync. */ @@ -324,7 +331,11 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len); \param s The modem context. \param coeffs The vector of complex coefficients. \return The number of coefficients in the vector. */ +#if defined(SPANDSP_USE_FIXED_POINT) +int v29_rx_equalizer_state(v29_rx_state_t *s, complexi16_t **coeffs); +#else int v29_rx_equalizer_state(v29_rx_state_t *s, complexf_t **coeffs); +#endif /*! Get the current received carrier frequency. \param s The modem context. diff --git a/libs/spandsp/src/spandsp/v8.h b/libs/spandsp/src/spandsp/v8.h index 3569524b20..0d621cd229 100644 --- a/libs/spandsp/src/spandsp/v8.h +++ b/libs/spandsp/src/spandsp/v8.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: v8.h,v 1.22 2008/05/14 15:41:25 steveu Exp $ + * $Id: v8.h,v 1.23 2008/09/04 14:40:05 steveu Exp $ */ /*! \file */ @@ -76,7 +76,7 @@ enum v8_modulation_e V8_MOD_V90 = (1 << 12), /* V.90 duplex */ V8_MOD_V92 = (1 << 13), /* V.92 duplex */ - V8_MOD_FAILED = (1 << 15), /* Indicates failure to negotiate */ + V8_MOD_FAILED = (1 << 15) /* Indicates failure to negotiate */ }; enum v8_protocol_e diff --git a/libs/spandsp/src/spandsp/vector_float.h b/libs/spandsp/src/spandsp/vector_float.h index 9f0febcb45..94c67cf33e 100644 --- a/libs/spandsp/src/spandsp/vector_float.h +++ b/libs/spandsp/src/spandsp/vector_float.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: vector_float.h,v 1.10 2008/04/17 14:27:01 steveu Exp $ + * $Id: vector_float.h,v 1.11 2008/09/01 16:07:34 steveu Exp $ */ #if !defined(_SPANDSP_VECTOR_FLOAT_H_) @@ -105,11 +105,26 @@ void vec_mul(double z[], const double x[], const double y[], int n); void vec_mull(long double z[], const long double x[], const long double y[], int n); #endif +/*! \brief Find the dot product of two float vectors. + \param x The first vector. + \param y The first vector. + \param n The number of elements in the vectors. + \return The dot product of the two vectors. */ float vec_dot_prodf(const float x[], const float y[], int n); +/*! \brief Find the dot product of two double vectors. + \param x The first vector. + \param y The first vector. + \param n The number of elements in the vectors. + \return The dot product of the two vectors. */ double vec_dot_prod(const double x[], const double y[], int n); #if defined(HAVE_LONG_DOUBLE) +/*! \brief Find the dot product of two long double vectors. + \param x The first vector. + \param y The first vector. + \param n The number of elements in the vectors. + \return The dot product of the two vectors. */ long double vec_dot_prodl(const long double x[], const long double y[], int n); #endif diff --git a/libs/spandsp/src/spandsp/vector_int.h b/libs/spandsp/src/spandsp/vector_int.h index 934a4848db..f603bd2143 100644 --- a/libs/spandsp/src/spandsp/vector_int.h +++ b/libs/spandsp/src/spandsp/vector_int.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: vector_int.h,v 1.10 2008/04/17 14:27:01 steveu Exp $ + * $Id: vector_int.h,v 1.11 2008/09/01 16:07:34 steveu Exp $ */ #if !defined(_SPANDSP_VECTOR_INT_H_) @@ -33,11 +33,79 @@ extern "C" { #endif +static __inline__ void vec_copyi(int z[], const int x[], int n) +{ + memcpy(z, x, n*sizeof(z[0])); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void vec_copyi16(int16_t z[], const int16_t x[], int n) +{ + memcpy(z, x, n*sizeof(z[0])); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void vec_copyi32(int32_t z[], const int32_t x[], int n) +{ + memcpy(z, x, n*sizeof(z[0])); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void vec_zeroi(int z[], int n) +{ + memset(z, 0, n*sizeof(z[0])); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void vec_zeroi16(int16_t z[], int n) +{ + memset(z, 0, n*sizeof(z[0])); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void vec_zeroi32(int32_t z[], int n) +{ + memset(z, 0, n*sizeof(z[0])); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void vec_seti(int z[], int x, int n) +{ + int i; + + for (i = 0; i < n; i++) + z[i] = x; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void vec_seti16(int16_t z[], int16_t x, int n) +{ + int i; + + for (i = 0; i < n; i++) + z[i] = x; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void vec_seti32(int32_t z[], int32_t x, int n) +{ + int i; + + for (i = 0; i < n; i++) + z[i] = x; +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Find the dot product of two int16_t vectors. + \param x The first vector. + \param y The first vector. + \param n The number of elements in the vectors. + \return The dot product of the two vectors. */ int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n); -/*! \brief Find the minimum and maximum values in a vector. +/*! \brief Find the minimum and maximum values in an int16_t vector. \param x The vector to be searched. - \param n The number of elements in the vetor. + \param n The number of elements in the vector. \param out A two element vector. The first will receive the maximum. The second will receive the minimum. This parameter may be set to NULL. diff --git a/libs/spandsp/src/spandsp/version.h b/libs/spandsp/src/spandsp/version.h index 9deb785346..ddd8f81175 100644 --- a/libs/spandsp/src/spandsp/version.h +++ b/libs/spandsp/src/spandsp/version.h @@ -30,8 +30,8 @@ /* The date and time of the version are in UTC form. */ -#define SPANDSP_RELEASE_DATE 20080829 -#define SPANDSP_RELEASE_TIME 104025 +#define SPANDSP_RELEASE_DATE 20080909 +#define SPANDSP_RELEASE_TIME 162813 #endif /*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c index dfc1e2e389..c74d6ff0a2 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.262 2008/08/17 16:25:52 steveu Exp $ + * $Id: t30.c,v 1.264 2008/09/09 15:30:43 steveu Exp $ */ /*! \file */ @@ -1831,7 +1831,6 @@ static int start_receiving_document(t30_state_t *s) } span_log(&s->logging, SPAN_LOG_FLOW, "Start receiving document\n"); queue_phase(s, T30_PHASE_B_TX); - s->dis_received = FALSE; s->ecm_block = 0; send_dis_or_dtc_sequence(s, TRUE); return 0; @@ -2006,7 +2005,6 @@ static int process_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len) send_dcn(s); return -1; } - s->dis_received = TRUE; if (set_dis_or_dtc(s)) { s->current_status = T30_ERR_INCOMPATIBLE; @@ -4823,13 +4821,13 @@ static void t30_non_ecm_rx_status(void *user_data, int status) s = (t30_state_t *) user_data; switch (status) { - case PUTBIT_TRAINING_IN_PROGRESS: + case SIG_STATUS_TRAINING_IN_PROGRESS: break; - case PUTBIT_TRAINING_FAILED: + case SIG_STATUS_TRAINING_FAILED: span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier training failed in state %d\n", s->state); s->rx_trained = FALSE; break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_SUCCEEDED: /* The modem is now trained */ span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier trained in state %d\n", s->state); /* In case we are in trainability test mode... */ @@ -4840,10 +4838,10 @@ static void t30_non_ecm_rx_status(void *user_data, int status) s->rx_trained = TRUE; s->timer_t2_t4 = 0; break; - case PUTBIT_CARRIER_UP: + case SIG_STATUS_CARRIER_UP: span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier up in state %d\n", s->state); break; - case PUTBIT_CARRIER_DOWN: + case SIG_STATUS_CARRIER_DOWN: span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier down in state %d\n", s->state); was_trained = s->rx_trained; s->rx_signal_present = FALSE; @@ -5052,7 +5050,7 @@ int t30_non_ecm_get_bit(void *user_data) if (s->tcf_test_bits-- < 0) { /* Finished sending training test. */ - bit = PUTBIT_END_OF_DATA; + bit = SIG_STATUS_END_OF_DATA; } break; case T30_STATE_I: @@ -5066,7 +5064,7 @@ int t30_non_ecm_get_bit(void *user_data) break; default: span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get_bit in bad state %d\n", s->state); - bit = PUTBIT_END_OF_DATA; + bit = SIG_STATUS_END_OF_DATA; break; } return bit; @@ -5150,19 +5148,19 @@ static void t30_hdlc_rx_status(void *user_data, int status) s = (t30_state_t *) user_data; switch (status) { - case PUTBIT_TRAINING_IN_PROGRESS: + case SIG_STATUS_TRAINING_IN_PROGRESS: break; - case PUTBIT_TRAINING_FAILED: + case SIG_STATUS_TRAINING_FAILED: span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier training failed in state %d\n", s->state); s->rx_trained = FALSE; break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_SUCCEEDED: /* The modem is now trained */ span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier trained in state %d\n", s->state); s->rx_signal_present = TRUE; s->rx_trained = TRUE; break; - case PUTBIT_CARRIER_UP: + case SIG_STATUS_CARRIER_UP: span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier up in state %d\n", s->state); s->rx_signal_present = TRUE; switch (s->timer_t2_t4_is) @@ -5177,7 +5175,7 @@ static void t30_hdlc_rx_status(void *user_data, int status) break; } break; - case PUTBIT_CARRIER_DOWN: + case SIG_STATUS_CARRIER_DOWN: span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier down in state %d\n", s->state); s->rx_signal_present = FALSE; s->rx_trained = FALSE; @@ -5206,7 +5204,7 @@ static void t30_hdlc_rx_status(void *user_data, int status) } } break; - case PUTBIT_FRAMING_OK: + case SIG_STATUS_FRAMING_OK: span_log(&s->logging, SPAN_LOG_FLOW, "HDLC framing OK in state %d\n", s->state); if (!s->far_end_detected && s->timer_t0_t1 > 0) { @@ -5232,7 +5230,7 @@ static void t30_hdlc_rx_status(void *user_data, int status) } } break; - case PUTBIT_ABORT: + case SIG_STATUS_ABORT: /* Just ignore these */ break; default: @@ -5559,10 +5557,10 @@ void t30_front_end_status(void *user_data, int status) switch (s->phase) { case T30_PHASE_C_NON_ECM_RX: - t30_non_ecm_rx_status(s, PUTBIT_CARRIER_DOWN); + t30_non_ecm_rx_status(s, SIG_STATUS_CARRIER_DOWN); break; default: - t30_hdlc_rx_status(s, PUTBIT_CARRIER_DOWN); + t30_hdlc_rx_status(s, SIG_STATUS_CARRIER_DOWN); break; } break; @@ -5584,8 +5582,8 @@ void t30_front_end_status(void *user_data, int status) case T30_PHASE_D_RX: /* We are running a V.21 receive modem, where an explicit training indication will not occur. */ - t30_hdlc_rx_status(s, PUTBIT_CARRIER_UP); - t30_hdlc_rx_status(s, PUTBIT_FRAMING_OK); + t30_hdlc_rx_status(s, SIG_STATUS_CARRIER_UP); + t30_hdlc_rx_status(s, SIG_STATUS_FRAMING_OK); break; default: /* Cancel any receive timeout, and declare that a receive signal is present, diff --git a/libs/spandsp/src/t31.c b/libs/spandsp/src/t31.c index d46caaf98c..2e7688e84c 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.119 2008/08/09 05:09:56 steveu Exp $ + * $Id: t31.c,v 1.120 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -341,7 +341,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, packets, when they have sent no data for the body of the frame. */ if (s->tx.out_bytes > 0) hdlc_accept((void *) s, fe->hdlc_rx.buf, fe->hdlc_rx.len, TRUE); - hdlc_accept((void *) s, NULL, PUTBIT_CARRIER_DOWN, TRUE); + hdlc_accept((void *) s, NULL, SIG_STATUS_CARRIER_DOWN, TRUE); } s->tx.out_bytes = 0; fe->missing_data = FALSE; @@ -352,7 +352,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD_SIG_END!\n"); span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad, sig end (%s)\n", t30_frametype(s->tx.data[2]), (fe->missing_data) ? "missing octets" : "clean"); if (fe->current_rx_type == T31_V21_RX) - hdlc_accept((void *) s, NULL, PUTBIT_CARRIER_DOWN, TRUE); + hdlc_accept((void *) s, NULL, SIG_STATUS_CARRIER_DOWN, TRUE); fe->hdlc_rx.len = 0; fe->missing_data = FALSE; break; @@ -363,7 +363,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, i.e. they send T38_FIELD_HDLC_FCS_OK, and then T38_FIELD_HDLC_SIG_END when the carrier actually drops. The other is because the HDLC signal drops unexpectedly - i.e. not just after a final frame. */ if (fe->current_rx_type == T31_V21_RX) - hdlc_accept((void *) s, NULL, PUTBIT_CARRIER_DOWN, TRUE); + hdlc_accept((void *) s, NULL, SIG_STATUS_CARRIER_DOWN, TRUE); fe->hdlc_rx.len = 0; fe->missing_data = FALSE; break; @@ -709,20 +709,20 @@ static void non_ecm_rx_status(void *user_data, int status) s = (t31_state_t *) user_data; switch (status) { - case PUTBIT_TRAINING_IN_PROGRESS: + case SIG_STATUS_TRAINING_IN_PROGRESS: break; - case PUTBIT_TRAINING_FAILED: + case SIG_STATUS_TRAINING_FAILED: s->at_state.rx_trained = FALSE; break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_SUCCEEDED: /* The modem is now trained */ at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT); s->at_state.rx_signal_present = TRUE; s->at_state.rx_trained = TRUE; break; - case PUTBIT_CARRIER_UP: + case SIG_STATUS_CARRIER_UP: break; - case PUTBIT_CARRIER_DOWN: + case SIG_STATUS_CARRIER_DOWN: if (s->at_state.rx_signal_present) { s->at_state.rx_data[s->at_state.rx_data_bytes++] = DLE; @@ -806,7 +806,7 @@ static int non_ecm_get_bit(void *user_data) s->tx.final = FALSE; /* This will put the modem into its shutdown sequence. When it has finally shut down, an OK response will be sent. */ - return PUTBIT_END_OF_DATA; + return SIG_STATUS_END_OF_DATA; } /* Fill with 0xFF bytes at the start of transmission, or 0x00 if we are in the middle of transmission. This follows T.31 and T.30 practice. */ @@ -856,24 +856,24 @@ static void hdlc_rx_status(void *user_data, int status) s = (t31_state_t *) user_data; switch (status) { - case PUTBIT_TRAINING_IN_PROGRESS: + case SIG_STATUS_TRAINING_IN_PROGRESS: break; - case PUTBIT_TRAINING_FAILED: + case SIG_STATUS_TRAINING_FAILED: s->at_state.rx_trained = FALSE; break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_SUCCEEDED: /* The modem is now trained */ s->at_state.rx_signal_present = TRUE; s->at_state.rx_trained = TRUE; break; - case PUTBIT_CARRIER_UP: + case SIG_STATUS_CARRIER_UP: if (s->modem == T31_CNG_TONE || s->modem == T31_NOCNG_TONE || s->modem == T31_V21_RX) { s->at_state.rx_signal_present = TRUE; s->rx_frame_received = FALSE; } break; - case PUTBIT_CARRIER_DOWN: + case SIG_STATUS_CARRIER_DOWN: if (s->rx_frame_received) { if (s->at_state.dte_is_waiting) @@ -899,7 +899,7 @@ static void hdlc_rx_status(void *user_data, int status) s->at_state.rx_signal_present = FALSE; s->at_state.rx_trained = FALSE; break; - case PUTBIT_FRAMING_OK: + case SIG_STATUS_FRAMING_OK: if (s->modem == T31_CNG_TONE || s->modem == T31_NOCNG_TONE) { /* Once we get any valid HDLC the CNG tone stops, and we drop @@ -949,7 +949,7 @@ static void hdlc_rx_status(void *user_data, int status) } } break; - case PUTBIT_ABORT: + case SIG_STATUS_ABORT: /* Just ignore these */ break; default: diff --git a/libs/spandsp/src/t38_gateway.c b/libs/spandsp/src/t38_gateway.c index ecc4315929..50da6e2147 100644 --- a/libs/spandsp/src/t38_gateway.c +++ b/libs/spandsp/src/t38_gateway.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: t38_gateway.c,v 1.139 2008/08/17 16:25:52 steveu Exp $ + * $Id: t38_gateway.c,v 1.142 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -308,31 +308,31 @@ static void hdlc_underflow_handler(void *user_data) span_log(&s->logging, SPAN_LOG_FLOW, "HDLC underflow at %d\n", t->out); /* If the current HDLC buffer is not at the HDLC_FLAG_PROCEED_WITH_OUTPUT stage, this underflow must be an end of preamble condition. */ - if ((t->flags[t->out] & HDLC_FLAG_PROCEED_WITH_OUTPUT)) + if ((t->buf[t->out].flags & HDLC_FLAG_PROCEED_WITH_OUTPUT)) { - old_data_type = t->contents[t->out]; - t->len[t->out] = 0; - t->flags[t->out] = 0; - t->contents[t->out] = 0; + old_data_type = t->buf[t->out].contents; + t->buf[t->out].len = 0; + t->buf[t->out].flags = 0; + t->buf[t->out].contents = 0; if (++t->out >= T38_TX_HDLC_BUFS) t->out = 0; - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC next is 0x%X\n", t->contents[t->out]); - if ((t->contents[t->out] & FLAG_INDICATOR)) + span_log(&s->logging, SPAN_LOG_FLOW, "HDLC next is 0x%X\n", t->buf[t->out].contents); + if ((t->buf[t->out].contents & FLAG_INDICATOR)) { /* The next thing in the queue is an indicator, so we need to stop this modem. */ span_log(&s->logging, SPAN_LOG_FLOW, "HDLC shutdown\n"); hdlc_tx_frame(&s->audio.modems.hdlc_tx, NULL, 0); } - else if ((t->contents[t->out] & FLAG_DATA)) + else if ((t->buf[t->out].contents & FLAG_DATA)) { /* Check if we should start sending the next frame */ - if ((t->flags[t->out] & HDLC_FLAG_PROCEED_WITH_OUTPUT)) + if ((t->buf[t->out].flags & HDLC_FLAG_PROCEED_WITH_OUTPUT)) { /* This frame is ready to go, and uses the same modem we are running now. So, send whatever we have. This might or might not be an entire frame. */ span_log(&s->logging, SPAN_LOG_FLOW, "HDLC start next frame\n"); - hdlc_tx_frame(&s->audio.modems.hdlc_tx, t->buf[t->out], t->len[t->out]); - if ((t->flags[t->out] & HDLC_FLAG_CORRUPT_CRC)) + hdlc_tx_frame(&s->audio.modems.hdlc_tx, t->buf[t->out].buf, t->buf[t->out].len); + if ((t->buf[t->out].flags & HDLC_FLAG_CORRUPT_CRC)) hdlc_tx_corrupt_frame(&s->audio.modems.hdlc_tx); /*endif*/ } @@ -355,9 +355,10 @@ static int set_next_tx_type(t38_gateway_state_t *s) t = &s->audio.modems; u = &s->core.hdlc_to_modem; + t38_non_ecm_buffer_report_output_status(&s->core.non_ecm_to_modem, &s->logging); if (t->next_tx_handler) { - /* There is a handler queued, so that is the next one */ + /* There is a handler queued, so that is the next one. */ t->tx_handler = t->next_tx_handler; t->tx_user_data = t->next_tx_user_data; t->next_tx_handler = NULL; @@ -378,13 +379,13 @@ static int set_next_tx_type(t38_gateway_state_t *s) if (u->in == u->out) return FALSE; /*endif*/ - if ((u->contents[u->out] & FLAG_INDICATOR) == 0) + if ((u->buf[u->out].contents & FLAG_INDICATOR) == 0) return FALSE; /*endif*/ - indicator = (u->contents[u->out] & 0xFF); - u->len[u->out] = 0; - u->flags[u->out] = 0; - u->contents[u->out] = 0; + indicator = (u->buf[u->out].contents & 0xFF); + u->buf[u->out].len = 0; + u->buf[u->out].flags = 0; + u->buf[u->out].contents = 0; if (++u->out >= T38_TX_HDLC_BUFS) u->out = 0; /*endif*/ @@ -437,7 +438,7 @@ static int set_next_tx_type(t38_gateway_state_t *s) hdlc_tx_init(&t->hdlc_tx, FALSE, 2, TRUE, hdlc_underflow_handler, s); hdlc_tx_flags(&t->hdlc_tx, 32); silence_gen_alter(&t->silence_gen, ms_to_samples(75)); - u->len[u->in] = 0; + u->buf[u->in].len = 0; fsk_tx_init(&t->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &t->hdlc_tx); t->tx_handler = (span_tx_handler_t *) &(silence_gen); t->tx_user_data = &t->silence_gen; @@ -456,6 +457,7 @@ static int set_next_tx_type(t38_gateway_state_t *s) t->tx_bit_rate = 2400; break; } + /*endswitch*/ silence_gen_alter(&t->silence_gen, ms_to_samples(75)); v27ter_tx_restart(&t->v27ter_tx, t->tx_bit_rate, t->use_tep); v27ter_tx_set_get_bit(&t->v27ter_tx, get_bit_func, get_bit_user_data); @@ -476,6 +478,7 @@ static int set_next_tx_type(t38_gateway_state_t *s) t->tx_bit_rate = 9600; break; } + /*endswitch*/ silence_gen_alter(&t->silence_gen, ms_to_samples(75)); v29_tx_restart(&t->v29_tx, t->tx_bit_rate, t->use_tep); v29_tx_set_get_bit(&t->v29_tx, get_bit_func, get_bit_user_data); @@ -525,6 +528,7 @@ static int set_next_tx_type(t38_gateway_state_t *s) t->tx_bit_rate = 14400; break; } + /*endswitch*/ silence_gen_alter(&t->silence_gen, ms_to_samples(75)); v17_tx_restart(&t->v17_tx, t->tx_bit_rate, t->use_tep, short_train); v17_tx_set_get_bit(&t->v17_tx, get_bit_func, get_bit_user_data); @@ -563,36 +567,41 @@ static int set_next_tx_type(t38_gateway_state_t *s) if (t->tx_bit_rate > 300) hdlc_tx_flags(&t->hdlc_tx, t->tx_bit_rate/(8*5)); /*endif*/ - t38_non_ecm_buffer_report_status(&s->core.non_ecm_to_modem, &s->logging); - t38_non_ecm_buffer_init(&s->core.non_ecm_to_modem, s->core.image_data_mode, s->core.min_row_bits); s->t38x.in_progress_rx_indicator = indicator; return TRUE; } /*- End of function --------------------------------------------------------*/ -static void pump_out_final_hdlc(t38_gateway_state_t *s, int good_fcs) +static void finalise_hdlc_frame(t38_gateway_state_t *s, int good_fcs) { - if (!good_fcs) - s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] |= HDLC_FLAG_CORRUPT_CRC; + t38_gateway_hdlc_buf_t *hdlc_buf; + + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + if (!good_fcs || (hdlc_buf->flags & HDLC_FLAG_MISSING_DATA)) + hdlc_buf->flags |= HDLC_FLAG_CORRUPT_CRC; /*endif*/ if (s->core.hdlc_to_modem.in == s->core.hdlc_to_modem.out) { /* This is the frame in progress at the output. */ - if ((s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.out] & HDLC_FLAG_PROCEED_WITH_OUTPUT) == 0) + if ((hdlc_buf->flags & HDLC_FLAG_PROCEED_WITH_OUTPUT) == 0) { /* Output of this frame has not yet begun. Throw it all out now. */ - hdlc_tx_frame(&s->audio.modems.hdlc_tx, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.out], s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.out]); + hdlc_tx_frame(&s->audio.modems.hdlc_tx, hdlc_buf->buf, hdlc_buf->len); } /*endif*/ - if ((s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.out] & HDLC_FLAG_CORRUPT_CRC)) + if ((hdlc_buf->flags & HDLC_FLAG_CORRUPT_CRC)) hdlc_tx_corrupt_frame(&s->audio.modems.hdlc_tx); /*endif*/ } /*endif*/ - s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] |= (HDLC_FLAG_PROCEED_WITH_OUTPUT | HDLC_FLAG_FINISHED); + hdlc_buf->flags |= (HDLC_FLAG_PROCEED_WITH_OUTPUT | HDLC_FLAG_FINISHED); if (++s->core.hdlc_to_modem.in >= T38_TX_HDLC_BUFS) s->core.hdlc_to_modem.in = 0; /*endif*/ + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + hdlc_buf->len = 0; + hdlc_buf->flags = 0; + hdlc_buf->contents = 0; } /*- End of function --------------------------------------------------------*/ @@ -853,53 +862,53 @@ static void monitor_control_messages(t38_gateway_state_t *s, int from_modem, uin static void queue_missing_indicator(t38_gateway_state_t *s, int data_type) { t38_core_state_t *t; + int expected; + int expected_alt; t = &s->t38x.t38; + expected = -1; + expected_alt = -1; /* Missing packets might have lost us the indicator that should have put us in the required mode of operation. It might be a bit late to fill in such a gap now, but we should try. We may also want to force indicators into the queue, such as when the data says 'end of signal'. */ + /* We have an expectation of whether long or short training should occur, but be + tolerant of either kind of indicator being present. */ switch (data_type) { case T38_DATA_NONE: - if (t->current_rx_indicator != T38_IND_NO_SIGNAL) - process_rx_indicator(t, (void *) s, T38_IND_NO_SIGNAL); + expected = T38_IND_NO_SIGNAL; break; case T38_DATA_V21: - if (t->current_rx_indicator != T38_IND_V21_PREAMBLE) - process_rx_indicator(t, (void *) s, T38_IND_V21_PREAMBLE); + expected = T38_IND_V21_PREAMBLE; break; case T38_DATA_V27TER_2400: - if (t->current_rx_indicator != T38_IND_V27TER_2400_TRAINING) - process_rx_indicator(t, (void *) s, T38_IND_V27TER_2400_TRAINING); + expected = T38_IND_V27TER_2400_TRAINING; break; case T38_DATA_V27TER_4800: - if (t->current_rx_indicator != T38_IND_V27TER_4800_TRAINING) - process_rx_indicator(t, (void *) s, T38_IND_V27TER_4800_TRAINING); + expected = T38_IND_V27TER_4800_TRAINING; break; case T38_DATA_V29_7200: - if (t->current_rx_indicator != T38_IND_V29_7200_TRAINING) - process_rx_indicator(t, (void *) s, T38_IND_V29_7200_TRAINING); + expected = T38_IND_V29_7200_TRAINING; break; case T38_DATA_V29_9600: - if (t->current_rx_indicator != T38_IND_V29_9600_TRAINING) - process_rx_indicator(t, (void *) s, T38_IND_V29_9600_TRAINING); + expected = T38_IND_V29_9600_TRAINING; break; case T38_DATA_V17_7200: - if (t->current_rx_indicator != T38_IND_V17_7200_SHORT_TRAINING && t->current_rx_indicator != T38_IND_V17_7200_LONG_TRAINING) - process_rx_indicator(t, (void *) s, T38_IND_V17_7200_LONG_TRAINING); + expected = (s->core.short_train) ? T38_IND_V17_7200_SHORT_TRAINING : T38_IND_V17_7200_LONG_TRAINING; + expected_alt = (s->core.short_train) ? T38_IND_V17_7200_LONG_TRAINING : T38_IND_V17_7200_SHORT_TRAINING; break; case T38_DATA_V17_9600: - if (t->current_rx_indicator != T38_IND_V17_9600_SHORT_TRAINING && t->current_rx_indicator != T38_IND_V17_9600_LONG_TRAINING) - process_rx_indicator(t, (void *) s, T38_IND_V17_9600_LONG_TRAINING); + expected = (s->core.short_train) ? T38_IND_V17_9600_SHORT_TRAINING : T38_IND_V17_9600_LONG_TRAINING; + expected_alt = (s->core.short_train) ? T38_IND_V17_9600_LONG_TRAINING : T38_IND_V17_9600_SHORT_TRAINING; break; case T38_DATA_V17_12000: - if (t->current_rx_indicator != T38_IND_V17_12000_SHORT_TRAINING && t->current_rx_indicator != T38_IND_V17_12000_LONG_TRAINING) - process_rx_indicator(t, (void *) s, T38_IND_V17_12000_LONG_TRAINING); + expected = (s->core.short_train) ? T38_IND_V17_12000_SHORT_TRAINING : T38_IND_V17_12000_LONG_TRAINING; + expected_alt = (s->core.short_train) ? T38_IND_V17_12000_LONG_TRAINING : T38_IND_V17_12000_SHORT_TRAINING; break; case T38_DATA_V17_14400: - if (t->current_rx_indicator != T38_IND_V17_14400_SHORT_TRAINING && t->current_rx_indicator != T38_IND_V17_14400_LONG_TRAINING) - process_rx_indicator(t, (void *) s, T38_IND_V17_14400_LONG_TRAINING); + expected = (s->core.short_train) ? T38_IND_V17_14400_SHORT_TRAINING : T38_IND_V17_14400_LONG_TRAINING; + expected_alt = (s->core.short_train) ? T38_IND_V17_14400_LONG_TRAINING : T38_IND_V17_14400_SHORT_TRAINING; break; case T38_DATA_V8: break; @@ -914,6 +923,20 @@ static void queue_missing_indicator(t38_gateway_state_t *s, int data_type) case T38_DATA_V33_14400: break; } + /*endswitch*/ + if (expected < 0) + return; + if (t->current_rx_indicator == expected) + return; + if (expected_alt >= 0 && t->current_rx_indicator == expected_alt) + return; + span_log(&s->logging, + SPAN_LOG_FLOW, + "Queuing missing indicator - %s\n", + t38_indicator_to_str(expected)); + process_rx_indicator(t, (void *) s, expected); + /* Force the indicator setting here, as the core won't set in when its missing. */ + t->current_rx_indicator = expected; } /*- End of function --------------------------------------------------------*/ @@ -922,7 +945,7 @@ static int process_rx_missing(t38_core_state_t *t, void *user_data, int rx_seq_n t38_gateway_state_t *s; s = (t38_gateway_state_t *) user_data; - s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] |= HDLC_FLAG_MISSING_DATA; + s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in].flags |= HDLC_FLAG_MISSING_DATA; return 0; } /*- End of function --------------------------------------------------------*/ @@ -933,23 +956,26 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica s = (t38_gateway_state_t *) user_data; + t38_non_ecm_buffer_report_input_status(&s->core.non_ecm_to_modem, &s->logging); if (t->current_rx_indicator == indicator) { /* This is probably due to the far end repeating itself. Ignore it. Its harmless */ return 0; } /*endif*/ - if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in]) + if (s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in].contents) { if (++s->core.hdlc_to_modem.in >= T38_TX_HDLC_BUFS) s->core.hdlc_to_modem.in = 0; /*endif*/ } /*endif*/ - s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (indicator | FLAG_INDICATOR); + s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in].contents = (indicator | FLAG_INDICATOR); if (++s->core.hdlc_to_modem.in >= T38_TX_HDLC_BUFS) s->core.hdlc_to_modem.in = 0; /*endif*/ + t38_non_ecm_buffer_set_mode(&s->core.non_ecm_to_modem, s->core.image_data_mode, s->core.min_row_bits); + span_log(&s->logging, SPAN_LOG_FLOW, "Queued change - (%d) %s -> %s\n", @@ -967,9 +993,9 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, int field_type, const uint8_t *buf, int len) { int i; - int previous; t38_gateway_state_t *s; t38_gateway_t38_state_t *xx; + t38_gateway_hdlc_buf_t *hdlc_buf; s = (t38_gateway_state_t *) user_data; xx = &s->t38x; @@ -977,46 +1003,52 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, { case T38_FIELD_HDLC_DATA: xx->current_rx_field_class = T38_FIELD_CLASS_HDLC; - if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA)) + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + if (hdlc_buf->contents != (data_type | FLAG_DATA)) + { queue_missing_indicator(s, data_type); + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + } /*endif*/ - previous = s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in]; /* Check if this data would overflow the buffer. */ - if (s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] + len > T38_MAX_HDLC_LEN) + if (hdlc_buf->len + len > T38_MAX_HDLC_LEN) break; /*endif*/ - s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (data_type | FLAG_DATA); - bit_reverse(&s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in][s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in]], buf, len); + hdlc_buf->contents = (data_type | FLAG_DATA); + bit_reverse(&hdlc_buf->buf[hdlc_buf->len], buf, len); /* We need to send out the control messages as they are arriving. They are - too slow to capture a whole frame, and then pass it on. + too slow to capture a whole frame before starting to pass it on. For the faster frames, take in the whole frame before sending it out. Also, there is no need to monitor, or modify, the contents of the faster frames. */ if (data_type == T38_DATA_V21) { for (i = 1; i <= len; i++) - edit_control_messages(s, 0, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in], s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] + i); + edit_control_messages(s, 0, hdlc_buf->buf, hdlc_buf->len + i); /*endfor*/ /* Don't start pumping data into the actual output stream until there is enough backlog to create some elasticity for jitter tolerance. */ - if (s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] + len >= HDLC_START_BUFFER_LEVEL) + if (hdlc_buf->len + len >= HDLC_START_BUFFER_LEVEL) { if (s->core.hdlc_to_modem.in == s->core.hdlc_to_modem.out) { - if ((s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] & HDLC_FLAG_PROCEED_WITH_OUTPUT) == 0) - previous = 0; + /* Output is not running, so kick it into life. */ + if ((hdlc_buf->flags & HDLC_FLAG_PROCEED_WITH_OUTPUT) == 0) + hdlc_tx_frame(&s->audio.modems.hdlc_tx, hdlc_buf->buf, hdlc_buf->len + len); + else + hdlc_tx_frame(&s->audio.modems.hdlc_tx, hdlc_buf->buf + hdlc_buf->len, len); /*endif*/ - hdlc_tx_frame(&s->audio.modems.hdlc_tx, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.out] + previous, s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.out] - previous + len); } /*endif*/ - s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] |= HDLC_FLAG_PROCEED_WITH_OUTPUT; + hdlc_buf->flags |= HDLC_FLAG_PROCEED_WITH_OUTPUT; } /*endif*/ } /*endif*/ - s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] += len; + s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in].len += len; break; case T38_FIELD_HDLC_FCS_OK: xx->current_rx_field_class = T38_FIELD_CLASS_HDLC; + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; if (len > 0) { span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK!\n"); @@ -1027,22 +1059,22 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, /* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK messages, in IFP packets with incrementing sequence numbers, which are actually repeats. They get through to this point because of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ - if (t->current_rx_data_type != data_type - || - t->current_rx_field_type != field_type) + if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) { - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC good\n", t30_frametype(s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in][2])); - if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA)) + span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC good\n", t30_frametype(hdlc_buf->buf[2])); + if (hdlc_buf->contents != (data_type | FLAG_DATA)) + { queue_missing_indicator(s, data_type); + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + } /*endif*/ - s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (data_type | FLAG_DATA); if (data_type == T38_DATA_V21) { - if ((s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] & HDLC_FLAG_MISSING_DATA) == 0) + if ((hdlc_buf->flags & HDLC_FLAG_MISSING_DATA) == 0) { - monitor_control_messages(s, FALSE, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in], s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in]); + monitor_control_messages(s, FALSE, hdlc_buf->buf, hdlc_buf->len); if (s->core.real_time_frame_handler) - s->core.real_time_frame_handler(s, s->core.real_time_frame_user_data, FALSE, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in], s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in]); + s->core.real_time_frame_handler(s, s->core.real_time_frame_user_data, FALSE, hdlc_buf->buf, hdlc_buf->len); /*endif*/ } /*endif*/ @@ -1050,21 +1082,21 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, else { /* Make sure we go back to short training if CTC/CTR has kicked us into - long training. Theer has to be more than one value HDLC frame in a - chunk of image data, so just setting short training mode heer should + long training. There has to be more than one value HDLC frame in a + chunk of image data, so just setting short training mode here should be enough. */ s->core.short_train = TRUE; } /*endif*/ - pump_out_final_hdlc(s, (s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] & HDLC_FLAG_MISSING_DATA) == 0); + hdlc_buf->contents = (data_type | FLAG_DATA); + finalise_hdlc_frame(s, TRUE); } /*endif*/ - s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] = 0; - s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] = 0; xx->corrupt_current_frame[0] = FALSE; break; case T38_FIELD_HDLC_FCS_BAD: xx->current_rx_field_class = T38_FIELD_CLASS_HDLC; + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; if (len > 0) { span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD!\n"); @@ -1077,24 +1109,32 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) { - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC bad\n", t30_frametype(s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in][2])); - if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA)) - queue_missing_indicator(s, data_type); - /*endif*/ - if (s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] > 0) + span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC bad\n", t30_frametype(hdlc_buf->buf[2])); + /* Only bother with frames that have a bad CRC, if they also have some content. */ + if (hdlc_buf->len > 0) { - s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (data_type | FLAG_DATA); - pump_out_final_hdlc(s, FALSE); + if (hdlc_buf->contents != (data_type | FLAG_DATA)) + { + queue_missing_indicator(s, data_type); + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + } + /*endif*/ + hdlc_buf->contents = (data_type | FLAG_DATA); + finalise_hdlc_frame(s, FALSE); + } + else + { + /* Just restart using the current frame buffer */ + hdlc_buf->contents = 0; } /*endif*/ } /*endif*/ - s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] = 0; - s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] = 0; xx->corrupt_current_frame[0] = FALSE; break; case T38_FIELD_HDLC_FCS_OK_SIG_END: xx->current_rx_field_class = T38_FIELD_CLASS_HDLC; + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; if (len > 0) { span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK_SIG_END!\n"); @@ -1107,23 +1147,35 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) { - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC OK, sig end\n", t30_frametype(s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in][2])); - if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA)) - queue_missing_indicator(s, data_type); - /*endif*/ - s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (data_type | FLAG_DATA); - if (data_type == T38_DATA_V21 && (s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] & HDLC_FLAG_MISSING_DATA) == 0) + span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC OK, sig end\n", t30_frametype(hdlc_buf->buf[2])); + if (hdlc_buf->contents != (data_type | FLAG_DATA)) { - monitor_control_messages(s, FALSE, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in], s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in]); - if (s->core.real_time_frame_handler) - s->core.real_time_frame_handler(s, s->core.real_time_frame_user_data, FALSE, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in], s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in]); - /*endif*/ + queue_missing_indicator(s, data_type); + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; } /*endif*/ - pump_out_final_hdlc(s, (s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] & HDLC_FLAG_MISSING_DATA) == 0); - s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] = 0; - s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] = 0; - s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = 0; + if (data_type == T38_DATA_V21) + { + if ((hdlc_buf->flags & HDLC_FLAG_MISSING_DATA) == 0) + { + monitor_control_messages(s, FALSE, hdlc_buf->buf, hdlc_buf->len); + if (s->core.real_time_frame_handler) + s->core.real_time_frame_handler(s, s->core.real_time_frame_user_data, FALSE, hdlc_buf->buf, hdlc_buf->len); + /*endif*/ + } + /*endif*/ + } + else + { + /* Make sure we go back to short training if CTC/CTR has kicked us into + long training. There has to be more than one value HDLC frame in a + chunk of image data, so just setting short training mode here should + be enough. */ + s->core.short_train = TRUE; + } + /*endif*/ + hdlc_buf->contents = (data_type | FLAG_DATA); + finalise_hdlc_frame(s, TRUE); queue_missing_indicator(s, T38_DATA_NONE); xx->current_rx_field_class = T38_FIELD_CLASS_NONE; } @@ -1132,6 +1184,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, break; case T38_FIELD_HDLC_FCS_BAD_SIG_END: xx->current_rx_field_class = T38_FIELD_CLASS_HDLC; + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; if (len > 0) { span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD_SIG_END!\n"); @@ -1144,19 +1197,25 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) { - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC bad, sig end\n", t30_frametype(s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in][2])); - if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA)) - queue_missing_indicator(s, data_type); - /*endif*/ - if (s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] > 0) + span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC bad, sig end\n", t30_frametype(hdlc_buf->buf[2])); + if (hdlc_buf->contents != (data_type | FLAG_DATA)) { - s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (data_type | FLAG_DATA); - pump_out_final_hdlc(s, FALSE); + queue_missing_indicator(s, data_type); + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + } + /*endif*/ + /* Only bother with frames that have a bad CRC, if they also have some content. */ + if (hdlc_buf->len > 0) + { + hdlc_buf->contents = (data_type | FLAG_DATA); + finalise_hdlc_frame(s, FALSE); + } + else + { + /* Just restart using the current frame buffer */ + hdlc_buf->contents = 0; } /*endif*/ - s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] = 0; - s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] = 0; - s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = 0; queue_missing_indicator(s, T38_DATA_NONE); xx->current_rx_field_class = T38_FIELD_CLASS_NONE; } @@ -1164,6 +1223,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, xx->corrupt_current_frame[0] = FALSE; break; case T38_FIELD_HDLC_SIG_END: + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; if (len > 0) { span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_SIG_END!\n"); @@ -1176,8 +1236,11 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) { - if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA)) + if (hdlc_buf->contents != (data_type | FLAG_DATA)) + { queue_missing_indicator(s, data_type); + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + } /* WORKAROUND: At least some Mediatrix boxes have a bug, where they can send this message at the end of non-ECM data. We need to tolerate this. */ if (xx->current_rx_field_class == T38_FIELD_CLASS_NON_ECM) @@ -1190,10 +1253,12 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, { /* This message is expected under 2 circumstances. One is as an alternative to T38_FIELD_HDLC_FCS_OK_SIG_END - i.e. they send T38_FIELD_HDLC_FCS_OK, and then T38_FIELD_HDLC_SIG_END when the carrier actually drops. - The other is because the HDLC signal drops unexpectedly - i.e. not just after a final frame. */ - s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] = 0; - s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] = 0; - s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = 0; + The other is because the HDLC signal drops unexpectedly - i.e. not just after a final frame. In + this case we just clear out any partial frame data that might be in the buffer. */ + /* TODO: what if any junk in the buffer has reached the HDLC_FLAG_PROCEED_WITH_OUTPUT stage? */ + hdlc_buf->len = 0; + hdlc_buf->flags = 0; + hdlc_buf->contents = 0; } /*endif*/ queue_missing_indicator(s, T38_DATA_NONE); @@ -1204,12 +1269,17 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, break; case T38_FIELD_T4_NON_ECM_DATA: xx->current_rx_field_class = T38_FIELD_CLASS_NON_ECM; - if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA)) + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + if (hdlc_buf->contents != (data_type | FLAG_DATA)) + { queue_missing_indicator(s, data_type); + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + } t38_non_ecm_buffer_inject(&s->core.non_ecm_to_modem, buf, len); xx->corrupt_current_frame[0] = FALSE; break; case T38_FIELD_T4_NON_ECM_SIG_END: + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; /* Some T.38 implementations send multiple T38_FIELD_T4_NON_ECM_SIG_END messages, in IFP packets with incrementing sequence numbers, which are actually repeats. They get through to this point because of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ @@ -1222,14 +1292,20 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, { if (len > 0) { - if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA)) + if (hdlc_buf->contents != (data_type | FLAG_DATA)) + { queue_missing_indicator(s, data_type); + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + } /*endif*/ t38_non_ecm_buffer_inject(&s->core.non_ecm_to_modem, buf, len); } /*endif*/ - if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA)) + if (hdlc_buf->contents != (data_type | FLAG_DATA)) + { queue_missing_indicator(s, data_type); + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + } /*endif*/ /* Don't flow control the data any more. Just pump out the remainder as fast as we can. */ t38_non_ecm_buffer_push(&s->core.non_ecm_to_modem); @@ -1237,12 +1313,16 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, else { span_log(&s->logging, SPAN_LOG_WARNING, "T38_FIELD_NON_ECM_SIG_END received at the end of HDLC data!\n"); - if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA)) + if (s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in].contents != (data_type | FLAG_DATA)) + { queue_missing_indicator(s, data_type); + hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in]; + } /*endif*/ - s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] = 0; - s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] = 0; - s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = 0; + /* TODO: what if any junk in the buffer has reached the HDLC_FLAG_PROCEED_WITH_OUTPUT stage? */ + hdlc_buf->len = 0; + hdlc_buf->flags = 0; + hdlc_buf->contents = 0; } /*endif*/ queue_missing_indicator(s, T38_DATA_NONE); @@ -1408,27 +1488,27 @@ static void non_ecm_rx_status(void *user_data, int status) s = (t38_gateway_state_t *) user_data; switch (status) { - case PUTBIT_TRAINING_IN_PROGRESS: + case SIG_STATUS_TRAINING_IN_PROGRESS: span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier training in progress\n"); if (s->core.tcf_mode_predictable_modem_start) s->core.tcf_mode_predictable_modem_start = 0; else announce_training(s); break; - case PUTBIT_TRAINING_FAILED: + case SIG_STATUS_TRAINING_FAILED: span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier training failed\n"); break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_SUCCEEDED: /* The modem is now trained */ span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier trained\n"); s->audio.modems.rx_signal_present = TRUE; s->audio.modems.rx_trained = TRUE; to_t38_buffer_init(&s->core.to_t38); break; - case PUTBIT_CARRIER_UP: + case SIG_STATUS_CARRIER_UP: span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier up\n"); break; - case PUTBIT_CARRIER_DOWN: + case SIG_STATUS_CARRIER_DOWN: span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier down\n"); s->core.tcf_mode_predictable_modem_start = 0; switch (s->t38x.current_tx_data_type) @@ -1573,26 +1653,23 @@ static void hdlc_rx_status(hdlc_rx_state_t *t, int status) t38_gateway_state_t *s; s = (t38_gateway_state_t *) t->user_data; + span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier status is %s (%d)\n", signal_status_to_str(status), status); switch (status) { - case PUTBIT_TRAINING_IN_PROGRESS: - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier training in progress\n"); + case SIG_STATUS_TRAINING_IN_PROGRESS: announce_training(s); break; - case PUTBIT_TRAINING_FAILED: - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier training failed\n"); + case SIG_STATUS_TRAINING_FAILED: break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_SUCCEEDED: /* The modem is now trained. */ - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier trained\n"); s->audio.modems.rx_signal_present = TRUE; s->audio.modems.rx_trained = TRUE; /* Behave like HDLC preamble has been announced. */ t->framing_ok_announced = TRUE; to_t38_buffer_init(&s->core.to_t38); break; - case PUTBIT_CARRIER_UP: - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier up\n"); + case SIG_STATUS_CARRIER_UP: /* Reset the HDLC receiver. */ t->raw_bit_stream = 0; t->len = 0; @@ -1601,8 +1678,7 @@ static void hdlc_rx_status(hdlc_rx_state_t *t, int status) t->framing_ok_announced = FALSE; to_t38_buffer_init(&s->core.to_t38); break; - case PUTBIT_CARRIER_DOWN: - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier down\n"); + case SIG_STATUS_CARRIER_DOWN: if (t->framing_ok_announced) { t38_core_send_data(&s->t38x.t38, s->t38x.current_tx_data_type, T38_FIELD_HDLC_SIG_END, NULL, 0, s->t38x.t38.data_end_tx_count); diff --git a/libs/spandsp/src/t38_non_ecm_buffer.c b/libs/spandsp/src/t38_non_ecm_buffer.c index e6c02b86a8..23b5c8f637 100644 --- a/libs/spandsp/src/t38_non_ecm_buffer.c +++ b/libs/spandsp/src/t38_non_ecm_buffer.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: t38_non_ecm_buffer.c,v 1.1 2008/08/14 14:06:05 steveu Exp $ + * $Id: t38_non_ecm_buffer.c,v 1.3 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -59,6 +59,21 @@ #include "spandsp/t38_non_ecm_buffer.h" +static void restart_buffer(t38_non_ecm_buffer_state_t *s) +{ + /* This should be called when draining the buffer is complete, which should + occur before any fresh data can possibly arrive to begin refilling it. */ + s->octet = 0xFF; + s->flow_control_fill_octet = 0xFF; + s->at_initial_all_ones = TRUE; + s->bit_stream = 0xFFFF; + s->out_ptr = 0; + s->in_ptr = 0; + s->latest_eol_ptr = 0; + s->data_finished = FALSE; +} +/*- End of function --------------------------------------------------------*/ + int t38_non_ecm_buffer_get_bit(void *user_data) { t38_non_ecm_buffer_state_t *s; @@ -80,12 +95,8 @@ int t38_non_ecm_buffer_get_bit(void *user_data) { /* The queue is empty, and we have received the end of data signal. This must really be the end to transmission. */ - s->data_finished = FALSE; - /* Reset the data pointers for next time. */ - s->out_ptr = 0; - s->in_ptr = 0; - s->latest_eol_ptr = 0; - return PUTBIT_END_OF_DATA; + restart_buffer(s); + return SIG_STATUS_END_OF_DATA; } /* The queue is blocked, but this does not appear to be the end of the data. Idle with fill octets, which should be safe at this point. */ @@ -160,10 +171,11 @@ void t38_non_ecm_buffer_inject(t38_non_ecm_buffer_state_t *s, const uint8_t *buf rough approach. */ while (s->row_bits < s->min_row_bits) { + s->min_row_bits_fill_octets++; s->data[s->in_ptr] = 0; s->row_bits += 8; - /* TODO: We can't buffer overflow, since we wrap around. However, the tail could overwrite - itself if things fall badly behind. */ + /* TODO: We can't buffer overflow, since we wrap around. However, the tail could + overwrite itself if things fall badly behind. */ s->in_ptr = (s->in_ptr + 1) & (T38_NON_ECM_TX_BUF_LEN - 1); } /* Start a new row */ @@ -205,28 +217,47 @@ void t38_non_ecm_buffer_inject(t38_non_ecm_buffer_state_t *s, const uint8_t *buf } /*- End of function --------------------------------------------------------*/ -void t38_non_ecm_buffer_report_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging) +void t38_non_ecm_buffer_report_input_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging) { - if (s->in_octets || s->out_octets) + if (s->in_octets || s->min_row_bits_fill_octets) { span_log(logging, SPAN_LOG_FLOW, - "%d incoming non-ECM octets, %d rows. %d outgoing non-ECM octets, %d rows\n", + "%d+%d incoming non-ECM octets, %d rows.\n", s->in_octets, - s->in_rows, - s->out_octets, - s->out_rows); + s->min_row_bits_fill_octets, + s->in_rows); + s->in_octets = 0; + s->in_rows = 0; + s->min_row_bits_fill_octets = 0; } - if (s->flow_control_fill_octets) +} +/*- End of function --------------------------------------------------------*/ + +void t38_non_ecm_buffer_report_output_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging) +{ + if (s->out_octets || s->flow_control_fill_octets) { span_log(logging, SPAN_LOG_FLOW, - "Non-ECM flow control generated %d octets\n", - s->flow_control_fill_octets); + "%d+%d outgoing non-ECM octets, %d rows.\n", + s->out_octets - s->flow_control_fill_octets, + s->flow_control_fill_octets, + s->out_rows); + s->out_octets = 0; + s->out_rows = 0; + s->flow_control_fill_octets = 0; } } /*- End of function --------------------------------------------------------*/ +void t38_non_ecm_buffer_set_mode(t38_non_ecm_buffer_state_t *s, int mode, int min_row_bits) +{ + s->image_data_mode = mode; + s->min_row_bits = min_row_bits; +} +/*- End of function --------------------------------------------------------*/ + t38_non_ecm_buffer_state_t *t38_non_ecm_buffer_init(t38_non_ecm_buffer_state_t *s, int mode, int min_row_bits) { memset(s, 0, sizeof(*s)); diff --git a/libs/spandsp/src/t38_terminal.c b/libs/spandsp/src/t38_terminal.c index 62a43070fb..fa96841991 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.100 2008/08/13 14:55:51 steveu Exp $ + * $Id: t38_terminal.c,v 1.101 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -192,7 +192,7 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica && (fe->current_rx_type == T30_MODEM_V21 || fe->current_rx_type == T30_MODEM_CNG)) { - t30_hdlc_accept(&s->t30, NULL, PUTBIT_CARRIER_DOWN, TRUE); + t30_hdlc_accept(&s->t30, NULL, SIG_STATUS_CARRIER_DOWN, TRUE); } fe->timeout_rx_samples = 0; t30_front_end_status(&s->t30, T30_FRONT_END_SIGNAL_ABSENT); @@ -357,7 +357,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, { span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK, sig end (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean"); t30_hdlc_accept(&s->t30, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing); - t30_hdlc_accept(&s->t30, NULL, PUTBIT_CARRIER_DOWN, TRUE); + t30_hdlc_accept(&s->t30, NULL, SIG_STATUS_CARRIER_DOWN, TRUE); } fe->hdlc_rx.len = 0; fe->rx_data_missing = FALSE; @@ -377,7 +377,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, { span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad, sig end (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean"); t30_hdlc_accept(&s->t30, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE); - t30_hdlc_accept(&s->t30, NULL, PUTBIT_CARRIER_DOWN, TRUE); + t30_hdlc_accept(&s->t30, NULL, SIG_STATUS_CARRIER_DOWN, TRUE); } fe->hdlc_rx.len = 0; fe->rx_data_missing = FALSE; @@ -410,7 +410,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, case T38_FIELD_T4_NON_ECM_DATA: if (!fe->rx_signal_present) { - t30_non_ecm_put_bit(&s->t30, PUTBIT_TRAINING_SUCCEEDED); + t30_non_ecm_put_bit(&s->t30, SIG_STATUS_TRAINING_SUCCEEDED); fe->rx_signal_present = TRUE; } bit_reverse(buf2, buf, len); @@ -427,7 +427,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, { if (!fe->rx_signal_present) { - t30_non_ecm_put_bit(&s->t30, PUTBIT_TRAINING_SUCCEEDED); + t30_non_ecm_put_bit(&s->t30, SIG_STATUS_TRAINING_SUCCEEDED); fe->rx_signal_present = TRUE; } bit_reverse(buf2, buf, len); diff --git a/libs/spandsp/src/t4.c b/libs/spandsp/src/t4.c index 249e8759ce..88348d6bbb 100644 --- a/libs/spandsp/src/t4.c +++ b/libs/spandsp/src/t4.c @@ -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: t4.c,v 1.112 2008/07/22 13:48:15 steveu Exp $ + * $Id: t4.c,v 1.113 2008/09/07 12:45:17 steveu Exp $ */ /* @@ -1963,7 +1963,7 @@ int t4_tx_get_bit(t4_state_t *s) int bit; if (s->bit_ptr >= s->image_size) - return PUTBIT_END_OF_DATA; + return SIG_STATUS_END_OF_DATA; bit = (s->image_buffer[s->bit_ptr] >> (7 - s->bit_pos)) & 1; if (--s->bit_pos < 0) { @@ -1999,7 +1999,7 @@ int t4_tx_check_bit(t4_state_t *s) int bit; if (s->bit_ptr >= s->image_size) - return PUTBIT_END_OF_DATA; + return SIG_STATUS_END_OF_DATA; bit = (s->image_buffer[s->bit_ptr] >> s->bit_pos) & 1; return bit; } diff --git a/libs/spandsp/src/v17rx.c b/libs/spandsp/src/v17rx.c index 1290454ca1..60a5cf3a3d 100644 --- a/libs/spandsp/src/v17rx.c +++ b/libs/spandsp/src/v17rx.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: v17rx.c,v 1.112 2008/07/17 19:12:27 steveu Exp $ + * $Id: v17rx.c,v 1.116 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -471,44 +471,14 @@ static int decode_baud(v17_rx_state_t *s, complexf_t *z) } /*- End of function --------------------------------------------------------*/ -static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) +static __inline__ void symbol_sync(v17_rx_state_t *s) { - static const complexf_t cdba[4] = - { - { 6.0f, 2.0f}, - {-2.0f, 6.0f}, - { 2.0f, -6.0f}, - {-6.0f, -2.0f} - }; - complexf_t z; - complexf_t zz; -#if defined(SPANDSP_USE_FIXED_POINTx) - const complexi_t *target; -#else - const complexf_t *target; -#endif + int i; float v; float p; - int bit; - int i; - int j; - int32_t angle; - int32_t ang; - int constellation_state; - /* This routine processes every half a baud, as we put things into the equalizer at the T/2 rate. - This routine adapts the position of the half baud samples, which the caller takes. */ + /* This routine adapts the position of the half baud samples entering the equalizer. */ - /* Add a sample to the equalizer's circular buffer, but don't calculate anything - at this time. */ - s->eq_buf[s->eq_step] = *sample; - s->eq_step = (s->eq_step + 1) & V17_EQUALIZER_MASK; - - /* On alternate insertions we have a whole baud and must process it. */ - if ((s->baud_half ^= 1)) - return; - - /* Symbol timing synchronisation */ /* Cross correlate */ v = s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_A + s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_B @@ -532,6 +502,48 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) s->eq_put_step += i; s->total_baud_timing_correction += i; } +} +/*- End of function --------------------------------------------------------*/ + +static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) +{ + static const complexf_t cdba[4] = + { + { 6.0f, 2.0f}, + {-2.0f, 6.0f}, + { 2.0f, -6.0f}, + {-6.0f, -2.0f} + }; + complexf_t z; + complexf_t zz; +#if defined(SPANDSP_USE_FIXED_POINTx) + const complexi_t *target; + static const complexi16_t zero = {0, 0}; +#else + const complexf_t *target; + static const complexf_t zero = {0, 0}; +#endif + float p; + int bit; + int i; + int j; + int32_t angle; + int32_t ang; + int constellation_state; + + /* This routine processes every half a baud, as we put things into the equalizer at the T/2 rate. */ + + /* Add a sample to the equalizer's circular buffer, but don't calculate anything + at this time. */ + s->eq_buf[s->eq_step] = *sample; + s->eq_step = (s->eq_step + 1) & V17_EQUALIZER_MASK; + + /* On alternate insertions we have a whole baud and must process it. */ + if ((s->baud_half ^= 1)) + return; + + /* Symbol timing synchronisation */ + symbol_sync(s); z = equalizer_get(s); @@ -545,7 +557,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) break; case TRAINING_STAGE_SYMBOL_ACQUISITION: /* Allow time for the symbol synchronisation to settle the symbol timing. */ - target = &z; + target = &zero; #if defined(IAXMODEM_STUFF) if (++s->training_count >= 100) #else @@ -562,7 +574,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) break; case TRAINING_STAGE_LOG_PHASE: /* Record the current alternate phase angle */ - target = &z; + target = &zero; angle = arctan2(z.im, z.re); s->training_count = 1; if (s->short_train) @@ -603,7 +615,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) } break; case TRAINING_STAGE_WAIT_FOR_CDBA: - target = &z; + target = &zero; angle = arctan2(z.im, z.re); /* Look for the initial ABAB sequence to display a phase reversal, which will signal the start of the scrambled CDBA segment */ @@ -665,7 +677,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) /* Park this modem */ s->agc_scaling_save = 0.0f; s->training_stage = TRAINING_STAGE_PARKED; - report_status_change(s, PUTBIT_TRAINING_FAILED); + report_status_change(s, SIG_STATUS_TRAINING_FAILED); break; } @@ -684,7 +696,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) descramble(s, 1); s->training_count = 1; s->training_stage = TRAINING_STAGE_COARSE_TRAIN_ON_CDBA; - report_status_change(s, PUTBIT_TRAINING_IN_PROGRESS); + report_status_change(s, SIG_STATUS_TRAINING_IN_PROGRESS); break; } if (++s->training_count > V17_TRAINING_SEG_1_LEN) @@ -695,7 +707,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) /* Park this modem */ s->agc_scaling_save = 0.0f; s->training_stage = TRAINING_STAGE_PARKED; - report_status_change(s, PUTBIT_TRAINING_FAILED); + report_status_change(s, SIG_STATUS_TRAINING_FAILED); } break; case TRAINING_STAGE_COARSE_TRAIN_ON_CDBA: @@ -767,7 +779,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) /* Park this modem */ s->agc_scaling_save = 0.0f; s->training_stage = TRAINING_STAGE_PARKED; - report_status_change(s, PUTBIT_TRAINING_FAILED); + report_status_change(s, SIG_STATUS_TRAINING_FAILED); } } break; @@ -806,8 +818,8 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) of a real training sequence. Note that this might be TEP. */ span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n"); /* Park this modem */ - report_status_change(s, PUTBIT_TRAINING_FAILED); s->training_stage = TRAINING_STAGE_PARKED; + report_status_change(s, SIG_STATUS_TRAINING_FAILED); } break; case TRAINING_STAGE_SHORT_TRAIN_ON_CDBA_AND_TEST: @@ -836,14 +848,14 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) { s->training_count = 0; s->training_stage = TRAINING_STAGE_TCM_WINDUP; - report_status_change(s, PUTBIT_TRAINING_IN_PROGRESS); + report_status_change(s, SIG_STATUS_TRAINING_IN_PROGRESS); } else { span_log(&s->logging, SPAN_LOG_FLOW, "Short training failed (convergence failed)\n"); /* Park this modem */ - report_status_change(s, PUTBIT_TRAINING_FAILED); s->training_stage = TRAINING_STAGE_PARKED; + report_status_change(s, SIG_STATUS_TRAINING_FAILED); } } break; @@ -883,7 +895,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) { /* We are up and running */ span_log(&s->logging, SPAN_LOG_FLOW, "Training succeeded (constellation mismatch %f)\n", s->training_error); - report_status_change(s, PUTBIT_TRAINING_SUCCEEDED); + report_status_change(s, SIG_STATUS_TRAINING_SUCCEEDED); /* Apply some lag to the carrier off condition, to ensure the last few bits get pushed through the processing. */ s->signal_present = 60; @@ -899,8 +911,8 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) /* Park this modem */ if (!s->short_train) s->agc_scaling_save = 0.0f; - report_status_change(s, PUTBIT_TRAINING_FAILED); s->training_stage = TRAINING_STAGE_PARKED; + report_status_change(s, SIG_STATUS_TRAINING_FAILED); } } break; @@ -908,7 +920,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) default: /* We failed to train! */ /* Park here until the carrier drops. */ - target = &z; + target = &zero; break; } if (s->qam_report) @@ -979,7 +991,7 @@ int v17_rx(v17_rx_state_t *s, const int16_t amp[], int len) /* Count down a short delay, to ensure we push the last few bits through the filters before stopping. */ v17_rx_restart(s, s->bit_rate, s->short_train); - report_status_change(s, PUTBIT_CARRIER_DOWN); + report_status_change(s, SIG_STATUS_CARRIER_DOWN); continue; } #if defined(IAXMODEM_STUFF) @@ -998,7 +1010,7 @@ int v17_rx(v17_rx_state_t *s, const int16_t amp[], int len) #if defined(IAXMODEM_STUFF) s->carrier_drop_pending = FALSE; #endif - report_status_change(s, PUTBIT_CARRIER_UP); + report_status_change(s, SIG_STATUS_CARRIER_UP); } if (s->training_stage == TRAINING_STAGE_PARKED) continue; @@ -1051,20 +1063,22 @@ int v17_rx(v17_rx_state_t *s, const int16_t amp[], int len) for (j = 1; j < V17_RX_FILTER_STEPS; j++) zi.im += (int32_t) rx_pulseshaper[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step]; sample.im = zi.im*s->agc_scaling; + s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2); + z = dds_lookup_complexf(s->carrier_phase); + zz.re = sample.re*z.re - sample.im*z.im; + zz.im = -sample.re*z.im - sample.im*z.re; + process_half_baud(s, &zz); #else zz.im = rx_pulseshaper[step][0].im*s->rrc_filter[s->rrc_filter_step]; for (j = 1; j < V17_RX_FILTER_STEPS; j++) zz.im += rx_pulseshaper[step][j].im*s->rrc_filter[j + s->rrc_filter_step]; sample.im = zz.im*s->agc_scaling; -#endif s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2); - /* Shift to baseband - since this is done in a full complex form, the - result is clean, and requires no further filtering, apart from the - equalizer. */ z = dds_lookup_complexf(s->carrier_phase); zz.re = sample.re*z.re - sample.im*z.im; zz.im = -sample.re*z.im - sample.im*z.re; process_half_baud(s, &zz); +#endif } dds_advancef(&(s->carrier_phase), s->carrier_phase_rate); } diff --git a/libs/spandsp/src/v17tx.c b/libs/spandsp/src/v17tx.c index b84955bb8e..89372bb81d 100644 --- a/libs/spandsp/src/v17tx.c +++ b/libs/spandsp/src/v17tx.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: v17tx.c,v 1.62 2008/07/16 14:23:47 steveu Exp $ + * $Id: v17tx.c,v 1.64 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -222,19 +222,19 @@ static __inline__ complexf_t getbaud(v17_tx_state_t *s) if (s->training_step == V17_TRAINING_SHUTDOWN_END) { if (s->status_handler) - s->status_handler(s->status_user_data, MODEM_TX_STATUS_SHUTDOWN_COMPLETE); + s->status_handler(s->status_user_data, SIG_STATUS_SHUTDOWN_COMPLETE); } } } bits = 0; for (i = 0; i < s->bits_per_symbol; i++) { - if ((bit = s->current_get_bit(s->get_bit_user_data)) == PUTBIT_END_OF_DATA) + if ((bit = s->current_get_bit(s->get_bit_user_data)) == SIG_STATUS_END_OF_DATA) { /* End of real data. Switch to the fake get_bit routine, until we have shut down completely. */ if (s->status_handler) - s->status_handler(s->status_user_data, MODEM_TX_STATUS_DATA_EXHAUSTED); + s->status_handler(s->status_user_data, SIG_STATUS_END_OF_DATA); s->current_get_bit = fake_get_bit; s->in_training = TRUE; bit = 1; diff --git a/libs/spandsp/src/v22bis_rx.c b/libs/spandsp/src/v22bis_rx.c index 46a1061f78..be9ac1efe2 100644 --- a/libs/spandsp/src/v22bis_rx.c +++ b/libs/spandsp/src/v22bis_rx.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: v22bis_rx.c,v 1.40 2008/07/25 13:56:54 steveu Exp $ + * $Id: v22bis_rx.c,v 1.41 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -607,7 +607,7 @@ int v22bis_rx(v22bis_state_t *s, const int16_t amp[], int len) if (power < s->rx.carrier_off_power) { v22bis_rx_restart(s, s->bit_rate); - s->put_bit(s->user_data, PUTBIT_CARRIER_DOWN); + s->put_bit(s->user_data, SIG_STATUS_CARRIER_DOWN); continue; } } @@ -617,7 +617,7 @@ int v22bis_rx(v22bis_state_t *s, const int16_t amp[], int len) if (power < s->rx.carrier_on_power) continue; s->rx.signal_present = TRUE; - s->put_bit(s->user_data, PUTBIT_CARRIER_UP); + s->put_bit(s->user_data, SIG_STATUS_CARRIER_UP); } if (s->rx.training != V22BIS_TRAINING_STAGE_PARKED) { diff --git a/libs/spandsp/src/v22bis_tx.c b/libs/spandsp/src/v22bis_tx.c index 815ac43dab..16db59e14a 100644 --- a/libs/spandsp/src/v22bis_tx.c +++ b/libs/spandsp/src/v22bis_tx.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: v22bis_tx.c,v 1.43 2008/07/02 14:48:26 steveu Exp $ + * $Id: v22bis_tx.c,v 1.44 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -302,7 +302,7 @@ static __inline__ int get_scrambled_bit(v22bis_state_t *s) { int bit; - if ((bit = s->tx.current_get_bit(s->user_data)) == PUTBIT_END_OF_DATA) + if ((bit = s->tx.current_get_bit(s->user_data)) == SIG_STATUS_END_OF_DATA) { /* Fill out this symbol with ones, and prepare to send the rest of the shutdown sequence. */ diff --git a/libs/spandsp/src/v27ter_rx.c b/libs/spandsp/src/v27ter_rx.c index f6d597f67c..5d6961d58e 100644 --- a/libs/spandsp/src/v27ter_rx.c +++ b/libs/spandsp/src/v27ter_rx.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: v27ter_rx.c,v 1.97 2008/08/04 14:03:17 steveu Exp $ + * $Id: v27ter_rx.c,v 1.101 2008/09/08 13:13:29 steveu Exp $ */ /*! \file */ @@ -48,6 +48,8 @@ #include "spandsp/complex.h" #include "spandsp/vector_float.h" #include "spandsp/complex_vector_float.h" +#include "spandsp/vector_int.h" +#include "spandsp/complex_vector_int.h" #include "spandsp/async.h" #include "spandsp/power_meter.h" #include "spandsp/arctan2.h" @@ -72,6 +74,11 @@ #define CARRIER_NOMINAL_FREQ 1800.0f #define EQUALIZER_DELTA 0.25f +#if defined(SPANDSP_USE_FIXED_POINT) +#define FP_FACTOR 4096 +#define FP_SHIFT_FACTOR 12 +#endif + /* Segments of the training sequence */ /* V.27ter defines a long and a short sequence. FAX doesn't use the short sequence, so it is not implemented here. */ @@ -90,17 +97,31 @@ enum TRAINING_STAGE_PARKED }; +#if defined(SPANDSP_USE_FIXED_POINTx) +static const complexi16_t v27ter_constellation[8] = +{ + {((int)(FP_FACTOR* 1.414f), ((int)(FP_FACTOR* 0.0f)}, /* 0deg */ + {((int)(FP_FACTOR* 1.0f), ((int)(FP_FACTOR* 1.0f)}, /* 45deg */ + {((int)(FP_FACTOR* 0.0f), ((int)(FP_FACTOR* 1.414f)}, /* 90deg */ + {((int)(FP_FACTOR*-1.0f), ((int)(FP_FACTOR* 1.0f)}, /* 135deg */ + {((int)(FP_FACTOR*-1.414f), ((int)(FP_FACTOR* 0.0f)}, /* 180deg */ + {((int)(FP_FACTOR*-1.0f), ((int)(FP_FACTOR*-1.0f)}, /* 225deg */ + {((int)(FP_FACTOR* 0.0f), ((int)(FP_FACTOR*-1.414f)}, /* 270deg */ + {((int)(FP_FACTOR* 1.0f), ((int)(FP_FACTOR*-1.0f)} /* 315deg */ +}; +#else static const complexf_t v27ter_constellation[8] = { - { 1.414f, 0.0f}, /* 0deg */ - { 1.0f, 1.0f}, /* 45deg */ - { 0.0f, 1.414f}, /* 90deg */ - {-1.0f, 1.0f}, /* 135deg */ - {-1.414f, 0.0f}, /* 180deg */ - {-1.0f, -1.0f}, /* 225deg */ - { 0.0f, -1.414f}, /* 270deg */ - { 1.0f, -1.0f} /* 315deg */ + { 1.414f, 0.0f}, /* 0deg */ + { 1.0f, 1.0f}, /* 45deg */ + { 0.0f, 1.414f}, /* 90deg */ + {-1.0f, 1.0f}, /* 135deg */ + {-1.414f, 0.0f}, /* 180deg */ + {-1.0f, -1.0f}, /* 225deg */ + { 0.0f, -1.414f}, /* 270deg */ + { 1.0f, -1.0f} /* 315deg */ }; +#endif float v27ter_rx_carrier_frequency(v27ter_rx_state_t *s) { @@ -149,14 +170,23 @@ static void report_status_change(v27ter_rx_state_t *s, int status) static void equalizer_save(v27ter_rx_state_t *s) { +#if defined(SPANDSP_USE_FIXED_POINTx) + cvec_copyi16(s->eq_coeff_save, s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); +#else cvec_copyf(s->eq_coeff_save, s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); +#endif } /*- End of function --------------------------------------------------------*/ static void equalizer_restore(v27ter_rx_state_t *s) { +#if defined(SPANDSP_USE_FIXED_POINTx) + cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); + cvec_zeroi16(s->eq_buf, V27TER_EQUALIZER_MASK); +#else cvec_copyf(s->eq_coeff, s->eq_coeff_save, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); cvec_zerof(s->eq_buf, V27TER_EQUALIZER_MASK); +#endif s->eq_put_step = (s->bit_rate == 4800) ? RX_PULSESHAPER_4800_COEFF_SETS*5/2 : RX_PULSESHAPER_2400_COEFF_SETS*20/(3*2); s->eq_step = 0; @@ -166,10 +196,16 @@ static void equalizer_restore(v27ter_rx_state_t *s) static void equalizer_reset(v27ter_rx_state_t *s) { - /* Start with an equalizer based on everything being perfect */ + /* Start with an equalizer based on everything being perfect. */ +#if defined(SPANDSP_USE_FIXED_POINTx) + cvec_zeroi16(s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); + s->eq_coeff[V27TER_EQUALIZER_PRE_LEN] = complex_seti16(1.414f*FP_FACTOR, 0); + cvec_zeroi16(s->eq_buf, V27TER_EQUALIZER_MASK); +#else cvec_zerof(s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); s->eq_coeff[V27TER_EQUALIZER_PRE_LEN] = complex_setf(1.414f, 0.0f); cvec_zerof(s->eq_buf, V27TER_EQUALIZER_MASK); +#endif s->eq_put_step = (s->bit_rate == 4800) ? RX_PULSESHAPER_4800_COEFF_SETS*5/2 : RX_PULSESHAPER_2400_COEFF_SETS*20/(3*2); s->eq_step = 0; @@ -177,60 +213,122 @@ static void equalizer_reset(v27ter_rx_state_t *s) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static __inline__ complexi16_t complex_mul_q4_12(const complexi16_t *x, const complexi16_t *y) +{ + complexi16_t z; + + z.re = ((int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im) >> 12; + z.im = ((int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re) >> 12; + return z; +} +/*- End of function --------------------------------------------------------*/ +#endif + +#if defined(SPANDSP_USE_FIXED_POINTx) +static __inline__ complexi16_t equalizer_get(v27ter_rx_state_t *s) +#else static __inline__ complexf_t equalizer_get(v27ter_rx_state_t *s) +#endif { int i; int p; +#if defined(SPANDSP_USE_FIXED_POINTx) + complexi16_t z; + complexi16_t z1; +#else complexf_t z; complexf_t z1; +#endif /* Get the next equalized value. */ - z = complex_setf(0.0f, 0.0f); p = s->eq_step - 1; +#if defined(SPANDSP_USE_FIXED_POINTx) + z = complex_seti16(0, 0); + for (i = 0; i < V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN; i++) + { + p = (p - 1) & V27TER_EQUALIZER_MASK; + z1 = complex_mul_q4_12(&s->eq_coeff[i], &s->eq_buf[p]); + z = complex_addi16(&z, &z1); + } +#else + z = complex_setf(0.0f, 0.0f); for (i = 0; i < V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN; i++) { p = (p - 1) & V27TER_EQUALIZER_MASK; z1 = complex_mulf(&s->eq_coeff[i], &s->eq_buf[p]); z = complex_addf(&z, &z1); } +#endif return z; } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static void tune_equalizer(v27ter_rx_state_t *s, const complexi16_t *z, const complexi16_t *target) +#else static void tune_equalizer(v27ter_rx_state_t *s, const complexf_t *z, const complexf_t *target) +#endif { int i; int p; +#if defined(SPANDSP_USE_FIXED_POINTx) + complexi16_t ez; + complexi16_t z1; +#else complexf_t ez; complexf_t z1; +#endif /* Find the x and y mismatch from the exact constellation position. */ +#if defined(SPANDSP_USE_FIXED_POINTx) + ez.re = target->re*FP_FACTOR - z->re; + ez.im = target->im*FP_FACTOR - z->im; + ez.re = ((int32_t) ez.re*(int32_t) s->eq_delta) >> 15; + ez.im = ((int32_t) ez.im*(int32_t) s->eq_delta) >> 15; +#else ez = complex_subf(target, z); ez.re *= s->eq_delta; ez.im *= s->eq_delta; +#endif p = s->eq_step - 1; for (i = 0; i < V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN; i++) { p = (p - 1) & V27TER_EQUALIZER_MASK; +#if defined(SPANDSP_USE_FIXED_POINTx) + z1 = complex_conji16(&s->eq_buf[p]); + z1 = complex_mul_q4_12(&ez, &z1); + s->eq_coeff[i] = complex_addi16(&s->eq_coeff[i], &z1); +#else z1 = complex_conjf(&s->eq_buf[p]); z1 = complex_mulf(&ez, &z1); s->eq_coeff[i] = complex_addf(&s->eq_coeff[i], &z1); /* Leak a little to tame uncontrolled wandering */ s->eq_coeff[i].re *= 0.9999f; s->eq_coeff[i].im *= 0.9999f; +#endif } } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static __inline__ void track_carrier(v27ter_rx_state_t *s, const complexi16_t *z, const complexi16_t *target) +#else static __inline__ void track_carrier(v27ter_rx_state_t *s, const complexf_t *z, const complexf_t *target) +#endif { float error; /* For small errors the imaginary part of the difference between the actual and the target positions is proportional to the phase error, for any particular target. However, the different amplitudes of the various target positions scale things. */ +#if defined(SPANDSP_USE_FIXED_POINTx) error = z->im*target->re - z->re*target->im; + error /= (float) FP_FACTOR; +#else + error = z->im*target->re - z->re*target->im; +#endif s->carrier_phase_rate += (int32_t) (s->carrier_track_i*error); s->carrier_phase += (int32_t) (s->carrier_track_p*error); @@ -295,7 +393,11 @@ static __inline__ void put_bit(v27ter_rx_state_t *s, int bit) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static __inline__ int find_quadrant(const complexi16_t *z) +#else static __inline__ int find_quadrant(const complexf_t *z) +#endif { int b1; int b2; @@ -307,7 +409,11 @@ static __inline__ int find_quadrant(const complexf_t *z) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static __inline__ int find_octant(complexi16_t *z) +#else static __inline__ int find_octant(complexf_t *z) +#endif { float abs_re; float abs_im; @@ -336,7 +442,11 @@ static __inline__ int find_octant(complexf_t *z) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static void decode_baud(v27ter_rx_state_t *s, complexi16_t *z) +#else static void decode_baud(v27ter_rx_state_t *s, complexf_t *z) +#endif { static const uint8_t phase_steps_4800[8] = { @@ -381,33 +491,12 @@ static void decode_baud(v27ter_rx_state_t *s, complexf_t *z) } /*- End of function --------------------------------------------------------*/ -static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t *sample) +static __inline__ void symbol_sync(v27ter_rx_state_t *s) { - static const int abab_pos[2] = - { - 0, 4 - }; - complexf_t z; - complexf_t zz; float p; float q; - int i; - int j; - int32_t angle; - int32_t ang; - /* Add a sample to the equalizer's circular buffer, but don't calculate anything - at this time. */ - s->eq_buf[s->eq_step] = *sample; - s->eq_step = (s->eq_step + 1) & V27TER_EQUALIZER_MASK; - - /* On alternate insertions we have a whole baud, and must process it. */ - if ((s->baud_phase ^= 1)) - { - //span_log(&s->logging, SPAN_LOG_FLOW, "Samp, %f, %f, %f, -1, 0x%X\n", z.re, z.im, sqrtf(z.re*z.re + z.im*z.im), s->eq_put_step); - return; - } - //span_log(&s->logging, SPAN_LOG_FLOW, "Samp, %f, %f, %f, 1, 0x%X\n", z.re, z.im, sqrtf(z.re*z.re + z.im*z.im), s->eq_put_step); + /* This routine adapts the position of the half baud samples entering the equalizer. */ /* Perform a Gardner test for baud alignment */ p = s->eq_buf[(s->eq_step - 3) & V27TER_EQUALIZER_MASK].re @@ -433,6 +522,37 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t s->gardner_integrate = 0; } //span_log(&s->logging, SPAN_LOG_FLOW, "Gardner=%10.5f 0x%X\n", p, s->eq_put_step); +} +/*- End of function --------------------------------------------------------*/ + +#if defined(SPANDSP_USE_FIXED_POINTx) +static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexi16_t *sample) +#else +static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t *sample) +#endif +{ + static const int abab_pos[2] = + { + 0, 4 + }; + complexf_t z; + complexf_t zz; + float p; + int i; + int j; + int32_t angle; + int32_t ang; + + /* Add a sample to the equalizer's circular buffer, but don't calculate anything + at this time. */ + s->eq_buf[s->eq_step] = *sample; + s->eq_step = (s->eq_step + 1) & V27TER_EQUALIZER_MASK; + + /* On alternate insertions we have a whole baud, and must process it. */ + if ((s->baud_half ^= 1)) + return; + + symbol_sync(s); z = equalizer_get(s); @@ -498,7 +618,7 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n"); /* Park this modem */ s->training_stage = TRAINING_STAGE_PARKED; - report_status_change(s, PUTBIT_TRAINING_FAILED); + report_status_change(s, SIG_STATUS_TRAINING_FAILED); break; } @@ -506,9 +626,20 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t buffer, as well as the carrier phase, for this to play out nicely. */ angle += 0x80000000; p = angle*2.0f*3.14159f/(65536.0f*65536.0f); +#if defined(SPANDSP_USE_FIXED_POINTx) + zz = complex_setf(cosf(p), -sinf(p)); + for (i = 0; i <= V27TER_EQUALIZER_MASK; i++) + { + z1 = complex_setf(s->eq_buf[i].re, s->eq_buf[i].im); + z1 = complex_mulf(&z1, &zz); + s->eq_buf[i].re = z1.re; + s->eq_buf[i].im = z1.im; + } +#else zz = complex_setf(cosf(p), -sinf(p)); for (i = 0; i <= V27TER_EQUALIZER_MASK; i++) s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz); +#endif s->carrier_phase += angle; s->gardner_step = 2; @@ -519,7 +650,7 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t descramble(s, 1); s->training_count = 1; s->training_stage = TRAINING_STAGE_TRAIN_ON_ABAB; - report_status_change(s, PUTBIT_TRAINING_IN_PROGRESS); + report_status_change(s, SIG_STATUS_TRAINING_IN_PROGRESS); } else if (++s->training_count > V27TER_TRAINING_SEG_3_LEN) { @@ -528,7 +659,7 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n"); /* Park this modem */ s->training_stage = TRAINING_STAGE_PARKED; - report_status_change(s, PUTBIT_TRAINING_FAILED); + report_status_change(s, SIG_STATUS_TRAINING_FAILED); } break; case TRAINING_STAGE_TRAIN_ON_ABAB: @@ -552,11 +683,22 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t case TRAINING_STAGE_TEST_ONES: decode_baud(s, &z); /* Measure the training error */ +#if defined(SPANDSP_USE_FIXED_POINTx) + z1.re = z.re/(float) FP_FACTOR; + z1.im = z.im/(float) FP_FACTOR; + if (s->bit_rate == 4800) + zz = complex_subf(&z, &v27ter_constellation[s->constellation_state]); + else + zz = complex_subf(&z, &v27ter_constellation[s->constellation_state << 1]); + zz = complex_subf(&z1, &zz); + s->training_error += powerf(&zz); +#else if (s->bit_rate == 4800) zz = complex_subf(&z, &v27ter_constellation[s->constellation_state]); else zz = complex_subf(&z, &v27ter_constellation[s->constellation_state << 1]); s->training_error += powerf(&zz); +#endif if (++s->training_count >= V27TER_TRAINING_SEG_6_LEN) { if ((s->bit_rate == 4800 && s->training_error < 0.5f) @@ -565,7 +707,7 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t { /* We are up and running */ span_log(&s->logging, SPAN_LOG_FLOW, "Training succeeded (constellation mismatch %f)\n", s->training_error); - report_status_change(s, PUTBIT_TRAINING_SUCCEEDED); + report_status_change(s, SIG_STATUS_TRAINING_SUCCEEDED); /* Apply some lag to the carrier off condition, to ensure the last few bits get pushed through the processing. */ s->signal_present = (s->bit_rate == 4800) ? 90 : 120; @@ -580,7 +722,7 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (constellation mismatch %f)\n", s->training_error); /* Park this modem */ s->training_stage = TRAINING_STAGE_PARKED; - report_status_change(s, PUTBIT_TRAINING_FAILED); + report_status_change(s, SIG_STATUS_TRAINING_FAILED); } } break; @@ -591,10 +733,21 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t } if (s->qam_report) { +#if defined(SPANDSP_USE_FIXED_POINTx) + z1.re = z.re/(float) FP_FACTOR; + z1.im = z.im/(float) FP_FACTOR; + zz.re = v27ter_constellation[s->constellation_state].re; + zz.im = v27ter_constellation[s->constellation_state].im; + s->qam_report(s->qam_user_data, + &z1, + &zz, + s->constellation_state); +#else s->qam_report(s->qam_user_data, &z, &v27ter_constellation[s->constellation_state], s->constellation_state); +#endif } } /*- End of function --------------------------------------------------------*/ @@ -607,10 +760,15 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) int16_t x; int32_t diff; complexf_t z; - complexf_t zz; - complexf_t sample; #if defined(SPANDSP_USE_FIXED_POINT) complexi_t zi; +#endif +#if defined(SPANDSP_USE_FIXED_POINTx) + complexi16_t sample; + complexi16_t zz; +#else + complexf_t sample; + complexf_t zz; #endif int32_t power; @@ -664,7 +822,7 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) /* Count down a short delay, to ensure we push the last few bits through the filters before stopping. */ v27ter_rx_restart(s, s->bit_rate, FALSE); - report_status_change(s, PUTBIT_CARRIER_DOWN); + report_status_change(s, SIG_STATUS_CARRIER_DOWN); continue; } #if defined(IAXMODEM_STUFF) @@ -683,7 +841,7 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) #if defined(IAXMODEM_STUFF) s->carrier_drop_pending = FALSE; #endif - report_status_change(s, PUTBIT_CARRIER_UP); + report_status_change(s, SIG_STATUS_CARRIER_UP); } /* Only spend effort processing this data if the modem is not parked, after training failure. */ @@ -697,7 +855,11 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) if (s->training_stage == TRAINING_STAGE_SYMBOL_ACQUISITION) { /* Only AGC during the initial training */ +#if defined(SPANDSP_USE_FIXED_POINTx) + s->agc_scaling = (float) FP_FACTOR*(1.0f/RX_PULSESHAPER_4800_GAIN)*1.414f/sqrtf(power); +#else s->agc_scaling = (1.0f/RX_PULSESHAPER_4800_GAIN)*1.414f/sqrtf(power); +#endif } /* Pulse shape while still at the carrier frequency, using a quadrature pair of filters. This results in a properly bandpass filtered complex @@ -789,7 +951,7 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) /* Count down a short delay, to ensure we push the last few bits through the filters before stopping. */ v27ter_rx_restart(s, s->bit_rate, FALSE); - report_status_change(s, PUTBIT_CARRIER_DOWN); + report_status_change(s, SIG_STATUS_CARRIER_DOWN); continue; } #if defined(IAXMODEM_STUFF) @@ -808,7 +970,7 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) #if defined(IAXMODEM_STUFF) s->carrier_drop_pending = FALSE; #endif - report_status_change(s, PUTBIT_CARRIER_UP); + report_status_change(s, SIG_STATUS_CARRIER_UP); } /* Only spend effort processing this data if the modem is not parked, after training failure. */ @@ -822,7 +984,11 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) if (s->training_stage == TRAINING_STAGE_SYMBOL_ACQUISITION) { /* Only AGC during the initial training */ +#if defined(SPANDSP_USE_FIXED_POINTx) + s->agc_scaling = (float) FP_FACTOR*(1.0f/RX_PULSESHAPER_2400_GAIN)*1.414f/sqrtf(power); +#else s->agc_scaling = (1.0f/RX_PULSESHAPER_2400_GAIN)*1.414f/sqrtf(power); +#endif } /* Pulse shape while still at the carrier frequency, using a quadrature pair of filters. This results in a properly bandpass filtered complex @@ -890,7 +1056,7 @@ int v27ter_rx_restart(v27ter_rx_state_t *s, int bit_rate, int old_train) s->bit_rate = bit_rate; #if defined(SPANDSP_USE_FIXED_POINT) - memset(s->rrc_filter, 0, sizeof(s->rrc_filter)); + vec_zeroi16(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0])); #else vec_zerof(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0])); #endif @@ -925,7 +1091,11 @@ int v27ter_rx_restart(v27ter_rx_state_t *s, int bit_rate, int old_train) else { s->carrier_phase_rate = dds_phase_ratef(CARRIER_NOMINAL_FREQ); +#if defined(SPANDSP_USE_FIXED_POINTx) + s->agc_scaling = (float) FP_FACTOR*0.005f/RX_PULSESHAPER_4800_GAIN; +#else s->agc_scaling = 0.005f/RX_PULSESHAPER_4800_GAIN; +#endif equalizer_reset(s); } s->eq_skip = 0; @@ -934,7 +1104,7 @@ int v27ter_rx_restart(v27ter_rx_state_t *s, int bit_rate, int old_train) s->gardner_integrate = 0; s->total_baud_timing_correction = 0; s->gardner_step = 512; - s->baud_phase = 0; + s->baud_half = 0; return 0; } diff --git a/libs/spandsp/src/v27ter_tx.c b/libs/spandsp/src/v27ter_tx.c index 218fc6d6b4..b74ae65e6c 100644 --- a/libs/spandsp/src/v27ter_tx.c +++ b/libs/spandsp/src/v27ter_tx.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: v27ter_tx.c,v 1.64 2008/07/16 14:23:47 steveu Exp $ + * $Id: v27ter_tx.c,v 1.66 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -108,12 +108,12 @@ static __inline__ int get_scrambled_bit(v27ter_tx_state_t *s) { int bit; - if ((bit = s->current_get_bit(s->get_bit_user_data)) == PUTBIT_END_OF_DATA) + if ((bit = s->current_get_bit(s->get_bit_user_data)) == SIG_STATUS_END_OF_DATA) { /* End of real data. Switch to the fake get_bit routine, until we have shut down completely. */ if (s->status_handler) - s->status_handler(s->status_user_data, MODEM_TX_STATUS_DATA_EXHAUSTED); + s->status_handler(s->status_user_data, SIG_STATUS_END_OF_DATA); s->current_get_bit = fake_get_bit; s->in_training = TRUE; bit = 1; @@ -212,7 +212,7 @@ static complexf_t getbaud(v27ter_tx_state_t *s) if (s->training_step == V27TER_TRAINING_SHUTDOWN_END) { if (s->status_handler) - s->status_handler(s->status_user_data, MODEM_TX_STATUS_SHUTDOWN_COMPLETE); + s->status_handler(s->status_user_data, SIG_STATUS_SHUTDOWN_COMPLETE); } } /* 4800bps uses 8 phases. 2400bps uses 4 phases. */ diff --git a/libs/spandsp/src/v29rx.c b/libs/spandsp/src/v29rx.c index 193279c545..298546d718 100644 --- a/libs/spandsp/src/v29rx.c +++ b/libs/spandsp/src/v29rx.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: v29rx.c,v 1.124 2008/07/17 19:12:27 steveu Exp $ + * $Id: v29rx.c,v 1.135 2008/09/09 16:13:12 steveu Exp $ */ /*! \file */ @@ -48,6 +48,8 @@ #include "spandsp/complex.h" #include "spandsp/vector_float.h" #include "spandsp/complex_vector_float.h" +#include "spandsp/vector_int.h" +#include "spandsp/complex_vector_int.h" #include "spandsp/async.h" #include "spandsp/power_meter.h" #include "spandsp/arctan2.h" @@ -67,6 +69,11 @@ #define BAUD_RATE 2400 #define EQUALIZER_DELTA 0.21f +#if defined(SPANDSP_USE_FIXED_POINT) +#define FP_FACTOR 4096 +#define FP_SHIFT_FACTOR 12 +#endif + /* Segments of the training sequence */ #define V29_TRAINING_SEG_2_LEN 128 #define V29_TRAINING_SEG_3_LEN 384 @@ -109,13 +116,23 @@ static const uint8_t space_map_9600[20][20] = }; /* Coefficients for the band edge symbol timing synchroniser (alpha = 0.99) */ -#define SYNC_LOW_BAND_EDGE_COEFF_0 1.829281f /* 2*alpha*cos(low_edge) */ -#define SYNC_LOW_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */ -#define SYNC_HIGH_BAND_EDGE_COEFF_0 -1.285907f /* 2*alpha*cos(high_edge) */ -#define SYNC_HIGH_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */ -#define SYNC_CROSS_CORR_COEFF_A -0.932131f /* -alpha^2*sin(freq_diff) */ -#define SYNC_CROSS_CORR_COEFF_B 0.752802f /* alpha*sin(high_edge) */ -#define SYNC_CROSS_CORR_COEFF_C -0.378857f /* -alpha*sin(low_edge) */ +#if defined(SPANDSP_USE_FIXED_POINT) +#define SYNC_LOW_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR* 1.829281f)) /* 2*alpha*cos(low_edge) */ +#define SYNC_LOW_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*-0.980100f)) /* -alpha^2 */ +#define SYNC_HIGH_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR*-1.285907f)) /* 2*alpha*cos(high_edge) */ +#define SYNC_HIGH_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*-0.980100f)) /* -alpha^2 */ +#define SYNC_CROSS_CORR_COEFF_A ((int)(FP_FACTOR*-0.932131f)) /* -alpha^2*sin(freq_diff) */ +#define SYNC_CROSS_CORR_COEFF_B ((int)(FP_FACTOR* 0.752802f)) /* alpha*sin(high_edge) */ +#define SYNC_CROSS_CORR_COEFF_C ((int)(FP_FACTOR*-0.378857f)) /* -alpha*sin(low_edge) */ +#else +#define SYNC_LOW_BAND_EDGE_COEFF_0 1.829281f /* 2*alpha*cos(low_edge) */ +#define SYNC_LOW_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */ +#define SYNC_HIGH_BAND_EDGE_COEFF_0 -1.285907f /* 2*alpha*cos(high_edge) */ +#define SYNC_HIGH_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */ +#define SYNC_CROSS_CORR_COEFF_A -0.932131f /* -alpha^2*sin(freq_diff) */ +#define SYNC_CROSS_CORR_COEFF_B 0.752802f /* alpha*sin(high_edge) */ +#define SYNC_CROSS_CORR_COEFF_C -0.378857f /* -alpha*sin(low_edge) */ +#endif float v29_rx_carrier_frequency(v29_rx_state_t *s) { @@ -143,19 +160,17 @@ float v29_rx_signal_power(v29_rx_state_t *s) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINT) +int v29_rx_equalizer_state(v29_rx_state_t *s, complexi16_t **coeffs) +#else int v29_rx_equalizer_state(v29_rx_state_t *s, complexf_t **coeffs) +#endif { *coeffs = s->eq_coeff; return V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; } /*- End of function --------------------------------------------------------*/ -static void equalizer_save(v29_rx_state_t *s) -{ - cvec_copyf(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); -} -/*- End of function --------------------------------------------------------*/ - static void report_status_change(v29_rx_state_t *s, int status) { if (s->status_handler) @@ -165,51 +180,105 @@ static void report_status_change(v29_rx_state_t *s, int status) } /*- End of function --------------------------------------------------------*/ +static void equalizer_save(v29_rx_state_t *s) +{ +#if defined(SPANDSP_USE_FIXED_POINT) + cvec_copyi16(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); +#else + cvec_copyf(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); +#endif +} +/*- End of function --------------------------------------------------------*/ + static void equalizer_restore(v29_rx_state_t *s) { +#if defined(SPANDSP_USE_FIXED_POINT) + cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); + cvec_zeroi16(s->eq_buf, V29_EQUALIZER_MASK); + s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); +#else cvec_copyf(s->eq_coeff, s->eq_coeff_save, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); cvec_zerof(s->eq_buf, V29_EQUALIZER_MASK); + s->eq_delta = EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); +#endif s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1; s->eq_step = 0; - s->eq_delta = EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); } /*- End of function --------------------------------------------------------*/ static void equalizer_reset(v29_rx_state_t *s) { /* Start with an equalizer based on everything being perfect */ +#if defined(SPANDSP_USE_FIXED_POINT) + cvec_zeroi16(s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); + s->eq_coeff[V29_EQUALIZER_PRE_LEN] = complex_seti16(3*FP_FACTOR, 0*FP_FACTOR); + cvec_zeroi16(s->eq_buf, V29_EQUALIZER_MASK); + s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); +#else cvec_zerof(s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); s->eq_coeff[V29_EQUALIZER_PRE_LEN] = complex_setf(3.0f, 0.0f); cvec_zerof(s->eq_buf, V29_EQUALIZER_MASK); + s->eq_delta = EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); +#endif s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1; s->eq_step = 0; - s->eq_delta = EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN); } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINT) +static __inline__ complexi16_t complex_mul_q4_12(const complexi16_t *x, const complexi16_t *y) +{ + complexi16_t z; + + z.re = ((int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im) >> 12; + z.im = ((int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re) >> 12; + return z; +} +/*- End of function --------------------------------------------------------*/ +#endif + +#if defined(SPANDSP_USE_FIXED_POINT) +static __inline__ complexi16_t equalizer_get(v29_rx_state_t *s) +#else static __inline__ complexf_t equalizer_get(v29_rx_state_t *s) +#endif { int i; int p; +#if defined(SPANDSP_USE_FIXED_POINT) + complexi16_t z; + complexi16_t z1; +#else complexf_t z; complexf_t z1; +#endif /* Get the next equalized value. */ - z = complex_setf(0.0f, 0.0f); p = s->eq_step - 1; +#if defined(SPANDSP_USE_FIXED_POINT) + z = complex_seti16(0, 0); + for (i = 0; i < V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; i++) + { + p = (p - 1) & V29_EQUALIZER_MASK; + z1 = complex_mul_q4_12(&s->eq_coeff[i], &s->eq_buf[p]); + z = complex_addi16(&z, &z1); + } +#else + z = complex_setf(0.0f, 0.0f); for (i = 0; i < V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; i++) { p = (p - 1) & V29_EQUALIZER_MASK; z1 = complex_mulf(&s->eq_coeff[i], &s->eq_buf[p]); z = complex_addf(&z, &z1); } +#endif return z; } /*- End of function --------------------------------------------------------*/ -#if defined(SPANDSP_USE_FIXED_POINTy) +#if defined(SPANDSP_USE_FIXED_POINT) static void tune_equalizer(v29_rx_state_t *s, const complexi16_t *z, const complexi16_t *target) #else static void tune_equalizer(v29_rx_state_t *s, const complexf_t *z, const complexf_t *target) @@ -217,24 +286,42 @@ static void tune_equalizer(v29_rx_state_t *s, const complexf_t *z, const complex { int i; int p; +#if defined(SPANDSP_USE_FIXED_POINT) + complexi16_t ez; + complexi16_t z1; +#else complexf_t ez; complexf_t z1; +#endif /* Find the x and y mismatch from the exact constellation position. */ +#if defined(SPANDSP_USE_FIXED_POINT) + ez.re = target->re*FP_FACTOR - z->re; + ez.im = target->im*FP_FACTOR - z->im; + ez.re = ((int32_t) ez.re*(int32_t) s->eq_delta) >> 15; + ez.im = ((int32_t) ez.im*(int32_t) s->eq_delta) >> 15; +#else ez = complex_subf(target, z); ez.re *= s->eq_delta; ez.im *= s->eq_delta; +#endif p = s->eq_step - 1; for (i = 0; i < V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; i++) { p = (p - 1) & V29_EQUALIZER_MASK; +#if defined(SPANDSP_USE_FIXED_POINT) + z1 = complex_conji16(&s->eq_buf[p]); + z1 = complex_mul_q4_12(&ez, &z1); + s->eq_coeff[i] = complex_addi16(&s->eq_coeff[i], &z1); +#else z1 = complex_conjf(&s->eq_buf[p]); z1 = complex_mulf(&ez, &z1); s->eq_coeff[i] = complex_addf(&s->eq_coeff[i], &z1); /* Leak a little to tame uncontrolled wandering */ s->eq_coeff[i].re *= 0.9999f; s->eq_coeff[i].im *= 0.9999f; +#endif } } /*- End of function --------------------------------------------------------*/ @@ -253,7 +340,7 @@ static int scrambled_training_bit(v29_rx_state_t *s) } /*- End of function --------------------------------------------------------*/ -#if defined(SPANDSP_USE_FIXED_POINTy) +#if defined(SPANDSP_USE_FIXED_POINT) static __inline__ int find_quadrant(const complexi16_t *z) #else static __inline__ int find_quadrant(const complexf_t *z) @@ -269,7 +356,7 @@ static __inline__ int find_quadrant(const complexf_t *z) } /*- End of function --------------------------------------------------------*/ -#if defined(SPANDSP_USE_FIXED_POINTy) +#if defined(SPANDSP_USE_FIXED_POINT) static __inline__ void track_carrier(v29_rx_state_t *s, const complexi16_t *z, const complexi16_t *target) #else static __inline__ void track_carrier(v29_rx_state_t *s, const complexf_t *z, const complexf_t *target) @@ -290,7 +377,12 @@ static __inline__ void track_carrier(v29_rx_state_t *s, const complexf_t *z, con different amplitudes of the various target positions scale things. This isn't all bad, as the angular error for the larger amplitude constellation points is probably a more reliable indicator, and we are weighting it as such. */ +#if defined(SPANDSP_USE_FIXED_POINT) error = z->im*target->re - z->re*target->im; + error /= (float) FP_FACTOR; +#else + error = z->im*target->re - z->re*target->im; +#endif /* Use a proportional-integral approach to tracking the carrier. The PI parameters are coarser at first, until we get precisely on target. Then, @@ -326,7 +418,11 @@ static __inline__ void put_bit(v29_rx_state_t *s, int bit) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINT) +static void decode_baud(v29_rx_state_t *s, complexi16_t *z) +#else static void decode_baud(v29_rx_state_t *s, complexf_t *z) +#endif { static const uint8_t phase_steps_9600[8] = { @@ -342,57 +438,51 @@ static void decode_baud(v29_rx_state_t *s, complexf_t *z) int re; int im; - switch (s->bit_rate) + if (s->bit_rate == 4800) { - case 9600: - default: + /* 4800 is a special case. */ + nearest = find_quadrant(z) << 1; + raw_bits = phase_steps_4800[((nearest - s->constellation_state) >> 1) & 3]; + put_bit(s, raw_bits); + put_bit(s, raw_bits >> 1); + } + else + { + /* 9600 and 7200 are quite similar. */ +#if defined(SPANDSP_USE_FIXED_POINT) + re = (z->re + 5*FP_FACTOR) >> (FP_SHIFT_FACTOR - 1); + im = (z->im + 5*FP_FACTOR) >> (FP_SHIFT_FACTOR - 1); +#else re = (int) ((z->re + 5.0f)*2.0f); + im = (int) ((z->im + 5.0f)*2.0f); +#endif if (re > 19) re = 19; else if (re < 0) re = 0; - im = (int) ((z->im + 5.0f)*2.0f); if (im > 19) im = 19; else if (im < 0) im = 0; nearest = space_map_9600[re][im]; - /* Deal with the amplitude bit */ - put_bit(s, nearest >> 3); + if (s->bit_rate == 9600) + { + /* Send out the top (amplitude) bit. */ + put_bit(s, nearest >> 3); + } + else + { + /* We can reuse the space map for 9600, but drop the top bit. */ + nearest &= 7; + } raw_bits = phase_steps_9600[(nearest - s->constellation_state) & 7]; for (i = 0; i < 3; i++) { put_bit(s, raw_bits); raw_bits >>= 1; } - break; - case 7200: - /* We can reuse the space map for 9600, but drop the top bit */ - re = (int) ((z->re + 5.0f)*2.0f); - if (re > 19) - re = 19; - else if (re < 0) - re = 0; - im = (int) ((z->im + 5.0f)*2.0f); - if (im > 19) - im = 19; - else if (im < 0) - im = 0; - nearest = space_map_9600[re][im] & 7; - raw_bits = phase_steps_9600[(nearest - s->constellation_state) & 7]; - for (i = 0; i < 3; i++) - { - put_bit(s, raw_bits); - raw_bits >>= 1; - } - break; - case 4800: - nearest = find_quadrant(z) << 1; - raw_bits = phase_steps_4800[((nearest - s->constellation_state) >> 1) & 3]; - put_bit(s, raw_bits); - put_bit(s, raw_bits >> 1); - break; } + track_carrier(s, z, &v29_9600_constellation[nearest]); if (--s->eq_skip <= 0) { @@ -406,7 +496,73 @@ static void decode_baud(v29_rx_state_t *s, complexf_t *z) } /*- End of function --------------------------------------------------------*/ +static __inline__ void symbol_sync(v29_rx_state_t *s) +{ + int i; +#if defined(SPANDSP_USE_FIXED_POINT) + int32_t v; + int32_t p; +#else + float v; + float p; +#endif + + /* This routine adapts the position of the half baud samples entering the equalizer. */ + +#if defined(SPANDSP_USE_FIXED_POINT) + /* TODO: The scalings used here need more thorough evaluation, to see if overflows are possible. */ + /* Cross correlate */ + v = (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_A + + (((s->symbol_sync_low[0] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_B + + (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[0] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_C; + /* Filter away any DC component */ + p = v - s->symbol_sync_dc_filter[1]; + s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0]; + s->symbol_sync_dc_filter[0] = v; + /* A little integration will now filter away much of the noise */ + s->baud_phase -= p; + if (abs(s->baud_phase) > 50*FP_FACTOR) + { + if (s->baud_phase > 0) + i = (s->baud_phase > 1000*FP_FACTOR) ? 5 : 1; + else + i = (s->baud_phase < -1000*FP_FACTOR) ? -5 : -1; + + //printf("v = %10.5f %5d - %f %f %d %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction); + s->eq_put_step += i; + s->total_baud_timing_correction += i; + } +#else + /* Cross correlate */ + v = s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_A + + s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_B + + s->symbol_sync_low[1]*s->symbol_sync_high[0]*SYNC_CROSS_CORR_COEFF_C; + /* Filter away any DC component */ + p = v - s->symbol_sync_dc_filter[1]; + s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0]; + s->symbol_sync_dc_filter[0] = v; + /* A little integration will now filter away much of the noise */ + s->baud_phase -= p; + if (fabsf(s->baud_phase) > 50.0f) + { + if (s->baud_phase > 0.0f) + i = (s->baud_phase > 1000.0f) ? 5 : 1; + else + i = (s->baud_phase < -1000.0f) ? -5 : -1; + + //printf("v = %10.5f %5d - %f %f %d %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction); + s->eq_put_step += i; + s->total_baud_timing_correction += i; + } +#endif +} +/*- End of function --------------------------------------------------------*/ + +#if defined(SPANDSP_USE_FIXED_POINT) +static void process_half_baud(v29_rx_state_t *s, complexi16_t *sample) +#else static void process_half_baud(v29_rx_state_t *s, complexf_t *sample) +#endif { static const int cdcd_pos[6] = { @@ -414,14 +570,17 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample) 0, 3, 0, 2 }; - complexf_t z; complexf_t zz; -#if defined(SPANDSP_USE_FIXED_POINTy) +#if defined(SPANDSP_USE_FIXED_POINT) + complexf_t z1; + complexi16_t z; const complexi16_t *target; + static const complexi16_t zero = {0, 0}; #else + complexf_t z; const complexf_t *target; + static const complexf_t zero = {0.0f, 0.0f}; #endif - float v; float p; int bit; int i; @@ -429,8 +588,7 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample) int32_t angle; int32_t ang; - /* This routine processes every half a baud, as we put things into the equalizer at the T/2 rate. - This routine adapts the position of the half baud samples, which the caller takes. */ + /* This routine processes every half a baud, as we put things into the equalizer at the T/2 rate. */ /* Add a sample to the equalizer's circular buffer, but don't calculate anything at this time. */ @@ -442,29 +600,7 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample) return; /* Symbol timing synchronisation */ - /* Cross correlate */ - v = s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_A - + s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_B - + s->symbol_sync_low[1]*s->symbol_sync_high[0]*SYNC_CROSS_CORR_COEFF_C; - - /* Filter away any DC component */ - p = v - s->symbol_sync_dc_filter[1]; - s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0]; - s->symbol_sync_dc_filter[0] = v; - /* A little integration will now filter away much of the noise */ - s->baud_phase -= p; - - if (fabsf(s->baud_phase) > 30.0f) - { - if (s->baud_phase > 0.0f) - i = (s->baud_phase > 1000.0f) ? 5 : 1; - else - i = (s->baud_phase < -1000.0f) ? -5 : -1; - - //printf("v = %10.5f %5d - %f %f %d %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction); - s->eq_put_step += i; - s->total_baud_timing_correction += i; - } + symbol_sync(s); z = equalizer_get(s); @@ -477,25 +613,27 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample) break; case TRAINING_STAGE_SYMBOL_ACQUISITION: /* Allow time for symbol synchronisation to settle the symbol timing. */ - target = &z; + target = &zero; if (++s->training_count >= 60) { /* Record the current phase angle */ s->training_stage = TRAINING_STAGE_LOG_PHASE; s->angles[0] = s->start_angles[0] = arctan2(z.im, z.re); + if (s->agc_scaling_save == 0.0f) + s->agc_scaling_save = s->agc_scaling; } break; case TRAINING_STAGE_LOG_PHASE: /* Record the current alternate phase angle */ - target = &z; + target = &zero; s->angles[1] = s->start_angles[1] = arctan2(z.im, z.re); s->training_count = 1; s->training_stage = TRAINING_STAGE_WAIT_FOR_CDCD; break; case TRAINING_STAGE_WAIT_FOR_CDCD: - target = &z; + target = &zero; angle = arctan2(z.im, z.re); /* Look for the initial ABAB sequence to display a phase reversal, which will signal the start of the scrambled CDCD segment */ @@ -524,24 +662,36 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample) || s->carrier_phase_rate > dds_phase_ratef(CARRIER_NOMINAL_FREQ + 20.0f)) { - span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n"); - /* Park this modem */ - s->training_stage = TRAINING_STAGE_PARKED; - report_status_change(s, PUTBIT_TRAINING_FAILED); - break; + span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n"); + /* Park this modem */ + s->agc_scaling_save = 0.0f; + s->training_stage = TRAINING_STAGE_PARKED; + report_status_change(s, SIG_STATUS_TRAINING_FAILED); + break; } /* Make a step shift in the phase, to pull it into line. We need to rotate the equalizer buffer, as well as the carrier phase, for this to play out nicely. */ p = angle*2.0f*3.14159f/(65536.0f*65536.0f); +#if defined(SPANDSP_USE_FIXED_POINT) + zz = complex_setf(cosf(p), -sinf(p)); + for (i = 0; i <= V29_EQUALIZER_MASK; i++) + { + z1 = complex_setf(s->eq_buf[i].re, s->eq_buf[i].im); + z1 = complex_mulf(&z1, &zz); + s->eq_buf[i].re = z1.re; + s->eq_buf[i].im = z1.im; + } +#else zz = complex_setf(cosf(p), -sinf(p)); for (i = 0; i <= V29_EQUALIZER_MASK; i++) s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz); +#endif s->carrier_phase += angle; /* We have just seen the first bit of the scrambled sequence, so skip it. */ bit = scrambled_training_bit(s); s->training_count = 1; s->training_stage = TRAINING_STAGE_TRAIN_ON_CDCD; - report_status_change(s, PUTBIT_TRAINING_IN_PROGRESS); + report_status_change(s, SIG_STATUS_TRAINING_IN_PROGRESS); break; } if (++s->training_count > V29_TRAINING_SEG_2_LEN) @@ -550,8 +700,9 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample) of a real training sequence. */ span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n"); /* Park this modem */ + s->agc_scaling_save = 0.0f; s->training_stage = TRAINING_STAGE_PARKED; - report_status_change(s, PUTBIT_TRAINING_FAILED); + report_status_change(s, SIG_STATUS_TRAINING_FAILED); } break; case TRAINING_STAGE_TRAIN_ON_CDCD: @@ -579,8 +730,17 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample) track_carrier(s, &z, target); tune_equalizer(s, &z, target); /* Measure the training error */ +#if defined(SPANDSP_USE_FIXED_POINT) + z1.re = z.re/(float) FP_FACTOR; + z1.im = z.im/(float) FP_FACTOR; + zz.re = target->re; + zz.im = target->im; + zz = complex_subf(&z1, &zz); + s->training_error += powerf(&zz); +#else zz = complex_subf(&z, target); s->training_error += powerf(&zz); +#endif if (++s->training_count >= V29_TRAINING_SEG_3_LEN) { span_log(&s->logging, SPAN_LOG_FLOW, "Constellation mismatch %f\n", s->training_error); @@ -595,8 +755,9 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample) { span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (convergence failed)\n"); /* Park this modem */ + s->agc_scaling_save = 0.0f; s->training_stage = TRAINING_STAGE_PARKED; - report_status_change(s, PUTBIT_TRAINING_FAILED); + report_status_change(s, SIG_STATUS_TRAINING_FAILED); } } break; @@ -607,15 +768,24 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample) decode_baud(s, &z); target = &v29_9600_constellation[s->constellation_state]; /* Measure the training error */ +#if defined(SPANDSP_USE_FIXED_POINT) + z1.re = z.re/(float) FP_FACTOR; + z1.im = z.im/(float) FP_FACTOR; + zz.re = target->re; + zz.im = target->im; + zz = complex_subf(&z1, &zz); + s->training_error += powerf(&zz); +#else zz = complex_subf(&z, target); s->training_error += powerf(&zz); +#endif if (++s->training_count >= V29_TRAINING_SEG_4_LEN) { if (s->training_error < 50.0f) { /* We are up and running */ span_log(&s->logging, SPAN_LOG_FLOW, "Training succeeded (constellation mismatch %f)\n", s->training_error); - report_status_change(s, PUTBIT_TRAINING_SUCCEEDED); + report_status_change(s, SIG_STATUS_TRAINING_SUCCEEDED); /* Apply some lag to the carrier off condition, to ensure the last few bits get pushed through the processing. */ s->signal_present = 60; @@ -629,8 +799,9 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample) /* Training has failed */ span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (constellation mismatch %f)\n", s->training_error); /* Park this modem */ - report_status_change(s, PUTBIT_TRAINING_FAILED); + s->agc_scaling_save = 0.0f; s->training_stage = TRAINING_STAGE_PARKED; + report_status_change(s, SIG_STATUS_TRAINING_FAILED); } } break; @@ -638,11 +809,21 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample) default: /* We failed to train! */ /* Park here until the carrier drops. */ - target = &z; + target = &zero; break; } if (s->qam_report) + { +#if defined(SPANDSP_USE_FIXED_POINT) + z1.re = z.re/(float) FP_FACTOR; + z1.im = z.im/(float) FP_FACTOR; + zz.re = target->re; + zz.im = target->im; + s->qam_report(s->qam_user_data, &z1, &zz, s->constellation_state); +#else s->qam_report(s->qam_user_data, &z, target, s->constellation_state); +#endif + } } /*- End of function --------------------------------------------------------*/ @@ -653,14 +834,19 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len) int step; int16_t x; int32_t diff; +#if defined(SPANDSP_USE_FIXED_POINT) + complexi16_t z; + complexi16_t zz; + complexi16_t sample; + int32_t v; + float y; +#else complexf_t z; complexf_t zz; complexf_t sample; -#if defined(SPANDSP_USE_FIXED_POINT) - complexi_t zi; + float v; #endif int32_t power; - float v; for (i = 0; i < len; i++) { @@ -709,7 +895,7 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len) /* Count down a short delay, to ensure we push the last few bits through the filters before stopping. */ v29_rx_restart(s, s->bit_rate, FALSE); - report_status_change(s, PUTBIT_CARRIER_DOWN); + report_status_change(s, SIG_STATUS_CARRIER_DOWN); continue; } #if defined(IAXMODEM_STUFF) @@ -728,7 +914,7 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len) #if defined(IAXMODEM_STUFF) s->carrier_drop_pending = FALSE; #endif - report_status_change(s, PUTBIT_CARRIER_UP); + report_status_change(s, SIG_STATUS_CARRIER_UP); } if (s->training_stage == TRAINING_STAGE_PARKED) continue; @@ -741,18 +927,29 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len) if (step < 0) step += RX_PULSESHAPER_COEFF_SETS; #if defined(SPANDSP_USE_FIXED_POINT) - zi.re = (int32_t) rx_pulseshaper[step][0].re*(int32_t) s->rrc_filter[s->rrc_filter_step]; + v = (int32_t) rx_pulseshaper[step][0].re*(int32_t) s->rrc_filter[s->rrc_filter_step]; for (j = 1; j < V29_RX_FILTER_STEPS; j++) - zi.re += (int32_t) rx_pulseshaper[step][j].re*(int32_t) s->rrc_filter[j + s->rrc_filter_step]; - sample.re = zi.re*s->agc_scaling; + v += (int32_t) rx_pulseshaper[step][j].re*(int32_t) s->rrc_filter[j + s->rrc_filter_step]; + y = v*s->agc_scaling; + sample.re = y; #else - zz.re = rx_pulseshaper[step][0].re*s->rrc_filter[s->rrc_filter_step]; + v = rx_pulseshaper[step][0].re*s->rrc_filter[s->rrc_filter_step]; for (j = 1; j < V29_RX_FILTER_STEPS; j++) - zz.re += rx_pulseshaper[step][j].re*s->rrc_filter[j + s->rrc_filter_step]; - sample.re = zz.re*s->agc_scaling; + v += rx_pulseshaper[step][j].re*s->rrc_filter[j + s->rrc_filter_step]; + sample.re = v*s->agc_scaling; #endif /* Symbol timing synchronisation band edge filters */ +#if defined(SPANDSP_USE_FIXED_POINT) + /* Low Nyquist band edge filter */ + v = ((s->symbol_sync_low[0]*SYNC_LOW_BAND_EDGE_COEFF_0) >> 12) + ((s->symbol_sync_low[1]*SYNC_LOW_BAND_EDGE_COEFF_1) >> 12) + sample.re; + s->symbol_sync_low[1] = s->symbol_sync_low[0]; + s->symbol_sync_low[0] = v; + /* High Nyquist band edge filter */ + v = ((s->symbol_sync_high[0]*SYNC_HIGH_BAND_EDGE_COEFF_0) >> 12) + ((s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_1) >> 12) + sample.re; + s->symbol_sync_high[1] = s->symbol_sync_high[0]; + s->symbol_sync_high[0] = v; +#else /* Low Nyquist band edge filter */ v = s->symbol_sync_low[0]*SYNC_LOW_BAND_EDGE_COEFF_0 + s->symbol_sync_low[1]*SYNC_LOW_BAND_EDGE_COEFF_1 + sample.re; s->symbol_sync_low[1] = s->symbol_sync_low[0]; @@ -761,16 +958,19 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len) v = s->symbol_sync_high[0]*SYNC_HIGH_BAND_EDGE_COEFF_0 + s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_1 + sample.re; s->symbol_sync_high[1] = s->symbol_sync_high[0]; s->symbol_sync_high[0] = v; - +#endif /* Put things into the equalization buffer at T/2 rate. The symbol synchronisation will fiddle the step to align this with the symbols. */ if (s->eq_put_step <= 0) { - if (s->training_stage == TRAINING_STAGE_SYMBOL_ACQUISITION) - { - /* Only AGC during the initial training */ + /* Only AGC until we have locked down the setting. */ +#if defined(SPANDSP_USE_FIXED_POINT) + if (s->agc_scaling_save == 0.0f) + s->agc_scaling = (float) FP_FACTOR*(1.0f/RX_PULSESHAPER_GAIN)*5.0f*0.25f/sqrtf(power); +#else + if (s->agc_scaling_save == 0.0f) s->agc_scaling = (1.0f/RX_PULSESHAPER_GAIN)*5.0f*0.25f/sqrtf(power); - } +#endif /* Pulse shape while still at the carrier frequency, using a quadrature pair of filters. This results in a properly bandpass filtered complex signal, which can be brought directly to baseband by complex mixing. @@ -778,24 +978,24 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len) step = -s->eq_put_step; if (step > RX_PULSESHAPER_COEFF_SETS - 1) step = RX_PULSESHAPER_COEFF_SETS - 1; -#if defined(SPANDSP_USE_FIXED_POINT) - zi.im = (int32_t) rx_pulseshaper[step][0].im*(int32_t) s->rrc_filter[s->rrc_filter_step]; - for (j = 1; j < V29_RX_FILTER_STEPS; j++) - zi.im += (int32_t) rx_pulseshaper[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step]; - sample.im = zi.im*s->agc_scaling; -#else - zz.im = rx_pulseshaper[step][0].im*s->rrc_filter[s->rrc_filter_step]; - for (j = 1; j < V29_RX_FILTER_STEPS; j++) - zz.im += rx_pulseshaper[step][j].im*s->rrc_filter[j + s->rrc_filter_step]; - sample.im = zz.im*s->agc_scaling; -#endif s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2); - /* Shift to baseband - since this is done in a full complex form, the - result is clean, and requires no further filtering, apart from the - equalizer. */ +#if defined(SPANDSP_USE_FIXED_POINT) + v = (int32_t) rx_pulseshaper[step][0].im*(int32_t) s->rrc_filter[s->rrc_filter_step]; + for (j = 1; j < V29_RX_FILTER_STEPS; j++) + v += (int32_t) rx_pulseshaper[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step]; + sample.im = v*s->agc_scaling; + z = dds_lookup_complexi16(s->carrier_phase); + zz.re = ((int32_t) sample.re*(int32_t) z.re - (int32_t) sample.im*(int32_t) z.im) >> 15; + zz.im = ((int32_t) -sample.re*(int32_t) z.im - (int32_t) sample.im*(int32_t) z.re) >> 15; +#else + v = rx_pulseshaper[step][0].im*s->rrc_filter[s->rrc_filter_step]; + for (j = 1; j < V29_RX_FILTER_STEPS; j++) + v += rx_pulseshaper[step][j].im*s->rrc_filter[j + s->rrc_filter_step]; + sample.im = v*s->agc_scaling; z = dds_lookup_complexf(s->carrier_phase); zz.re = sample.re*z.re - sample.im*z.im; zz.im = -sample.re*z.im - sample.im*z.re; +#endif process_half_baud(s, &zz); } dds_advancef(&(s->carrier_phase), s->carrier_phase_rate); @@ -837,7 +1037,7 @@ int v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train) s->bit_rate = bit_rate; #if defined(SPANDSP_USE_FIXED_POINT) - memset(s->rrc_filter, 0, sizeof(s->rrc_filter)); + vec_zeroi16(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0])); #else vec_zerof(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0])); #endif @@ -856,8 +1056,6 @@ int v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train) s->old_train = old_train; s->carrier_phase = 0; - s->carrier_track_i = 8000.0f; - s->carrier_track_p = 8000000.0f; power_meter_init(&(s->power), 4); @@ -872,13 +1070,29 @@ int v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train) else { s->carrier_phase_rate = dds_phase_ratef(CARRIER_NOMINAL_FREQ); + s->agc_scaling_save = 0.0f; +#if defined(SPANDSP_USE_FIXED_POINT) + s->agc_scaling = (float) FP_FACTOR*0.0017f/RX_PULSESHAPER_GAIN; +#else s->agc_scaling = 0.0017f/RX_PULSESHAPER_GAIN; +#endif equalizer_reset(s); } - s->eq_skip = 0; + s->carrier_track_i = 8000.0f; + s->carrier_track_p = 8000000.0f; s->last_sample = 0; + s->eq_skip = 0; /* Initialise the working data for symbol timing synchronisation */ +#if defined(SPANDSP_USE_FIXED_POINT) + s->symbol_sync_low[0] = 0; + s->symbol_sync_low[1] = 0; + s->symbol_sync_high[0] = 0; + s->symbol_sync_high[1] = 0; + s->symbol_sync_dc_filter[0] = 0; + s->symbol_sync_dc_filter[1] = 0; + s->baud_phase = 0; +#else s->symbol_sync_low[0] = 0.0f; s->symbol_sync_low[1] = 0.0f; s->symbol_sync_high[0] = 0.0f; @@ -886,6 +1100,7 @@ int v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train) s->symbol_sync_dc_filter[0] = 0.0f; s->symbol_sync_dc_filter[1] = 0.0f; s->baud_phase = 0.0f; +#endif s->baud_half = 0; s->total_baud_timing_correction = 0; diff --git a/libs/spandsp/src/v29tx.c b/libs/spandsp/src/v29tx.c index 1375383544..2e2a3ebc33 100644 --- a/libs/spandsp/src/v29tx.c +++ b/libs/spandsp/src/v29tx.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: v29tx.c,v 1.76 2008/07/16 14:23:47 steveu Exp $ + * $Id: v29tx.c,v 1.79 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -54,10 +54,6 @@ #include "spandsp/v29tx.h" -#if defined(SPANDSP_USE_FIXED_POINT) -#define SPANDSP_USE_FIXED_POINTx -#endif - #include "v29tx_constellation_maps.h" #if defined(SPANDSP_USE_FIXED_POINT) #include "v29tx_fixed_rrc.h" @@ -87,12 +83,12 @@ static __inline__ int get_scrambled_bit(v29_tx_state_t *s) int bit; int out_bit; - if ((bit = s->current_get_bit(s->get_bit_user_data)) == PUTBIT_END_OF_DATA) + if ((bit = s->current_get_bit(s->get_bit_user_data)) == SIG_STATUS_END_OF_DATA) { /* End of real data. Switch to the fake get_bit routine, until we have shut down completely. */ if (s->status_handler) - s->status_handler(s->status_user_data, MODEM_TX_STATUS_DATA_EXHAUSTED); + s->status_handler(s->status_user_data, SIG_STATUS_END_OF_DATA); s->current_get_bit = fake_get_bit; s->in_training = TRUE; bit = 1; @@ -166,7 +162,7 @@ static __inline__ complexf_t getbaud(v29_tx_state_t *s) if (s->training_step == V29_TRAINING_SHUTDOWN_END) { if (s->status_handler) - s->status_handler(s->status_user_data, MODEM_TX_STATUS_SHUTDOWN_COMPLETE); + s->status_handler(s->status_user_data, SIG_STATUS_SHUTDOWN_COMPLETE); } } /* 9600bps uses the full constellation. diff --git a/libs/spandsp/src/v29tx_constellation_maps.h b/libs/spandsp/src/v29tx_constellation_maps.h index a9a7b9aafd..1984c0b28f 100644 --- a/libs/spandsp/src/v29tx_constellation_maps.h +++ b/libs/spandsp/src/v29tx_constellation_maps.h @@ -23,10 +23,10 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: v29tx_constellation_maps.h,v 1.1 2008/07/10 13:34:01 steveu Exp $ + * $Id: v29tx_constellation_maps.h,v 1.2 2008/09/04 14:40:05 steveu Exp $ */ -#if defined(SPANDSP_USE_FIXED_POINTx) +#if defined(SPANDSP_USE_FIXED_POINT) static const complexi16_t v29_abab_constellation[6] = #else static const complexf_t v29_abab_constellation[6] = @@ -40,7 +40,7 @@ static const complexf_t v29_abab_constellation[6] = {-3, 0} /* 180deg low */ }; -#if defined(SPANDSP_USE_FIXED_POINTx) +#if defined(SPANDSP_USE_FIXED_POINT) static const complexi16_t v29_cdcd_constellation[6] = #else static const complexf_t v29_cdcd_constellation[6] = @@ -54,7 +54,7 @@ static const complexf_t v29_cdcd_constellation[6] = { 0, 3} /* 90deg low */ }; -#if defined(SPANDSP_USE_FIXED_POINTx) +#if defined(SPANDSP_USE_FIXED_POINT) static const complexi16_t v29_9600_constellation[16] = #else static const complexf_t v29_9600_constellation[16] = diff --git a/libs/spandsp/src/v42.c b/libs/spandsp/src/v42.c index 2954e2f857..004915578e 100644 --- a/libs/spandsp/src/v42.c +++ b/libs/spandsp/src/v42.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: v42.c,v 1.42 2008/05/13 13:17:25 steveu Exp $ + * $Id: v42.c,v 1.43 2008/09/07 12:45:17 steveu Exp $ */ /* THIS IS A WORK IN PROGRESS. IT IS NOT FINISHED. */ @@ -721,31 +721,7 @@ fprintf(stderr, "LAPM receive %d %d\n", ok, len); if (len < 0) { /* Special conditions */ - switch (len) - { - case PUTBIT_TRAINING_FAILED: - span_log(&s->logging, SPAN_LOG_DEBUG, "Training failed\n"); - break; - case PUTBIT_TRAINING_SUCCEEDED: - span_log(&s->logging, SPAN_LOG_DEBUG, "Training succeeded\n"); - break; - case PUTBIT_CARRIER_UP: - span_log(&s->logging, SPAN_LOG_DEBUG, "Carrier up\n"); - break; - case PUTBIT_CARRIER_DOWN: - span_log(&s->logging, SPAN_LOG_DEBUG, "Carrier down\n"); - break; - case PUTBIT_FRAMING_OK: - span_log(&s->logging, SPAN_LOG_DEBUG, "Framing OK\n"); - break; - case PUTBIT_ABORT: - span_log(&s->logging, SPAN_LOG_DEBUG, "Abort\n"); - break; - default: - span_log(&s->logging, SPAN_LOG_DEBUG, "Eh!\n"); - break; - } - /*endswitch*/ + span_log(&s->logging, SPAN_LOG_DEBUG, "V.42 rx status is %s (%d)\n", signal_status_to_str(len), len); return; } /*endif*/ @@ -1133,19 +1109,7 @@ static void negotiation_rx_bit(v42_state_t *s, int new_bit) if (new_bit < 0) { /* Special conditions */ - switch (new_bit) - { - case PUTBIT_CARRIER_UP: - break; - case PUTBIT_CARRIER_DOWN: - case PUTBIT_TRAINING_SUCCEEDED: - case PUTBIT_TRAINING_FAILED: - break; - default: - span_log(&s->logging, SPAN_LOG_WARNING, "Unexpected special 'bit' code %d\n", new_bit); - break; - } - /*endswitch*/ + span_log(&s->logging, SPAN_LOG_DEBUG, "V.42 rx status is %s (%d)\n", signal_status_to_str(new_bit), new_bit); return; } /*endif*/ diff --git a/libs/spandsp/src/v8.c b/libs/spandsp/src/v8.c index 03a4482741..cc311dc23a 100644 --- a/libs/spandsp/src/v8.c +++ b/libs/spandsp/src/v8.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: v8.c,v 1.30 2008/07/02 14:48:26 steveu Exp $ + * $Id: v8.c,v 1.31 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -396,10 +396,10 @@ static void put_bit(void *user_data, int bit) /* Special conditions */ switch (bit) { - case PUTBIT_CARRIER_UP: - case PUTBIT_CARRIER_DOWN: - case PUTBIT_TRAINING_SUCCEEDED: - case PUTBIT_TRAINING_FAILED: + case SIG_STATUS_CARRIER_UP: + case SIG_STATUS_CARRIER_DOWN: + case SIG_STATUS_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_FAILED: break; default: break; diff --git a/libs/spandsp/src/vector_int.c b/libs/spandsp/src/vector_int.c index 7492547f85..3f19eefda4 100644 --- a/libs/spandsp/src/vector_int.c +++ b/libs/spandsp/src/vector_int.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: vector_int.c,v 1.11 2008/07/02 14:48:26 steveu Exp $ + * $Id: vector_int.c,v 1.12 2008/09/01 16:07:34 steveu Exp $ */ /*! \file */ @@ -87,7 +87,7 @@ int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n) " .p2align 2;\n" "1:\n" - " addl $24,%%edx;\n" /* now edx = top - 8 */ + " addl $24,%%edx;\n" /* Now edx = top - 8 */ " cmpl %%edx,%%esi;\n" " ja 3f;\n" @@ -106,7 +106,7 @@ int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n) " .p2align 2;\n" "3:\n" - " addl $4,%%edx;\n" /* now edx = top - 4 */ + " addl $4,%%edx;\n" /* Now edx = top - 4 */ " cmpl %%edx,%%esi;\n" " ja 5f;\n" @@ -121,7 +121,7 @@ int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n) " .p2align 2;\n" "5:\n" - " addl $2,%%edx;\n" /* now edx = top - 2 */ + " addl $2,%%edx;\n" /* Now edx = top - 2 */ " cmpl %%edx,%%esi;\n" " ja 6f;\n" @@ -141,7 +141,7 @@ int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n) " movq %%mm0,%%mm1;\n" " punpckhdq %%mm0,%%mm1;\n" " paddd %%mm1,%%mm0;\n" - /* et voila, eax has the final result */ + /* Et voila, eax has the final result */ " movd %%mm0,%%eax;\n" " emms;\n" diff --git a/libs/spandsp/tests/Makefile.am b/libs/spandsp/tests/Makefile.am index e5cbad1149..4d965f3dec 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.105 2008/08/16 15:45:45 steveu Exp $ +## $Id: Makefile.am,v 1.106 2008/09/09 14:05:55 steveu Exp $ AM_CFLAGS = $(COMP_VENDOR_CFLAGS) AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS) @@ -274,7 +274,7 @@ tone_generate_tests_SOURCES = tone_generate_tests.c tone_generate_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp tsb85_tests_SOURCES = tsb85_tests.c fax_tester.c -tsb85_tests_LDADD = $(LIBDIR) -lspandsp +tsb85_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp v17_tests_SOURCES = v17_tests.c line_model_monitor.cpp modem_monitor.cpp v17_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp diff --git a/libs/spandsp/tests/bert_tests.c b/libs/spandsp/tests/bert_tests.c index 3e577a3538..1c37e9d3b0 100644 --- a/libs/spandsp/tests/bert_tests.c +++ b/libs/spandsp/tests/bert_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: bert_tests.c,v 1.24 2008/05/13 13:17:25 steveu Exp $ + * $Id: bert_tests.c,v 1.25 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -423,7 +423,7 @@ int main(int argc, char *argv[]) bert_set_report(&bert, 100000, reporter, (intptr_t) 0); for (;;) { - if ((bit = bert_get_bit(&bert)) == PUTBIT_END_OF_DATA) + if ((bit = bert_get_bit(&bert)) == SIG_STATUS_END_OF_DATA) { bert_result(&bert, &bert_results); printf("Rate test: %d bits, %d bad bits, %d resyncs\n", bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); diff --git a/libs/spandsp/tests/echo_monitor.cpp b/libs/spandsp/tests/echo_monitor.cpp index f11585b71a..4e7a8241da 100644 --- a/libs/spandsp/tests/echo_monitor.cpp +++ b/libs/spandsp/tests/echo_monitor.cpp @@ -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: echo_monitor.cpp,v 1.12 2008/05/27 15:08:21 steveu Exp $ + * $Id: echo_monitor.cpp,v 1.13 2008/09/08 16:10:41 steveu Exp $ */ #ifdef HAVE_CONFIG_H @@ -56,44 +56,49 @@ #include "spandsp.h" #include "echo_monitor.h" -Fl_Double_Window *w; +struct line_model_monitor_s +{ + Fl_Double_Window *w; -Fl_Audio_Meter *audio_meter; + Fl_Audio_Meter *audio_meter; + Fl_Group *c_spec; + Fl_Group *c_right; + Fl_Group *c_can; + Fl_Group *c_line_model; -Fl_Group *c_spec; -Fl_Group *c_right; -Fl_Group *c_can; -Fl_Group *c_line_model; + Ca_Canvas *canvas_spec; + Ca_X_Axis *spec_freq; + Ca_Y_Axis *spec_amp; + Ca_Line *spec_re; + double spec_re_plot[2*512]; -Ca_Canvas *canvas_spec; -Ca_X_Axis *spec_freq; -Ca_Y_Axis *spec_amp; -Ca_Line *spec_re = NULL; -double spec_re_plot[2*512]; + Ca_Canvas *canvas_can; + Ca_X_Axis *can_x; + Ca_Y_Axis *can_y; + Ca_Line *can_re; + double can_re_plot[512]; -Ca_Canvas *canvas_can; -Ca_X_Axis *can_x; -Ca_Y_Axis *can_y; -Ca_Line *can_re = NULL; -double can_re_plot[512]; + Ca_Canvas *canvas_line_model; + Ca_X_Axis *line_model_x; + Ca_Y_Axis *line_model_y; + Ca_Line *line_model_re; + double line_model_re_plot[512]; + + int in_ptr; +#if defined(HAVE_FFTW3_H) + double in[1024][2]; + double out[1024][2]; +#else + fftw_complex in[1024]; + fftw_complex out[1024]; +#endif + fftw_plan p; +}; -Ca_Canvas *canvas_line_model; -Ca_X_Axis *line_model_x; -Ca_Y_Axis *line_model_y; -Ca_Line *line_model_re = NULL; -double line_model_re_plot[512]; static int skip = 0; - -int in_ptr; -#if defined(HAVE_FFTW3_H) -double in[1024][2]; -double out[1024][2]; -#else -fftw_complex in[1024]; -fftw_complex out[1024]; -#endif -fftw_plan p; +static struct line_model_monitor_s echo; +static struct line_model_monitor_s *s = &echo; int echo_can_monitor_can_update(const int16_t *coeffs, int len) { @@ -101,25 +106,25 @@ int echo_can_monitor_can_update(const int16_t *coeffs, int len) float min; float max; - if (can_re) - delete can_re; + if (s->can_re) + delete s->can_re; - canvas_can->current(canvas_can); + s->canvas_can->current(s->canvas_can); i = 0; min = coeffs[i]; max = coeffs[i]; for (i = 0; i < len; i++) { - can_re_plot[2*i] = i; - can_re_plot[2*i + 1] = coeffs[i]; + s->can_re_plot[2*i] = i; + s->can_re_plot[2*i + 1] = coeffs[i]; if (min > coeffs[i]) min = coeffs[i]; if (max < coeffs[i]) max = coeffs[i]; } - can_y->maximum((max == min) ? max + 0.2 : max); - can_y->minimum(min); - can_re = new Ca_Line(len, can_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); + s->can_y->maximum((max == min) ? max + 0.2 : max); + s->can_y->minimum(min); + s->can_re = new Ca_Line(len, s->can_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); if (++skip >= 100) { skip = 0; @@ -135,25 +140,25 @@ int echo_can_monitor_line_model_update(const int32_t *coeffs, int len) float min; float max; - if (line_model_re) - delete line_model_re; + if (s->line_model_re) + delete s->line_model_re; - canvas_line_model->current(canvas_line_model); + s->canvas_line_model->current(s->canvas_line_model); i = 0; min = coeffs[i]; max = coeffs[i]; for (i = 0; i < len; i++) { - line_model_re_plot[2*i] = i; - line_model_re_plot[2*i + 1] = coeffs[i]; + s->line_model_re_plot[2*i] = i; + s->line_model_re_plot[2*i + 1] = coeffs[i]; if (min > coeffs[i]) min = coeffs[i]; if (max < coeffs[i]) max = coeffs[i]; } - line_model_y->maximum((max == min) ? max + 0.2 : max); - line_model_y->minimum(min); - line_model_re = new Ca_Line(len, line_model_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); + s->line_model_y->maximum((max == min) ? max + 0.2 : max); + s->line_model_y->minimum(min); + s->line_model_re = new Ca_Line(len, s->line_model_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); if (++skip >= 100) { skip = 0; @@ -169,18 +174,18 @@ int echo_can_monitor_line_spectrum_update(const int16_t amp[], int len) int x; for (i = 0; i < len; i++) - audio_meter->sample(amp[i]/32768.0); + s->audio_meter->sample(amp[i]/32768.0); - if (in_ptr + len < 512) + if (s->in_ptr + len < 512) { /* Just add this fragment to the buffer. */ for (i = 0; i < len; i++) #if defined(HAVE_FFTW3_H) - in[in_ptr + i][0] = amp[i]; + s->in[s->in_ptr + i][0] = amp[i]; #else - in[in_ptr + i].re = amp[i]; + s->in[s->in_ptr + i].re = amp[i]; #endif - in_ptr += len; + s->in_ptr += len; return 0; } if (len >= 512) @@ -190,9 +195,9 @@ int echo_can_monitor_line_spectrum_update(const int16_t amp[], int len) x = len - 512; for (i = 0; i < 512; i++) #if defined(HAVE_FFTW3_H) - in[i][0] = amp[x + i]; + s->in[i][0] = amp[x + i]; #else - in[i].re = amp[x + i]; + s->in[i].re = amp[x + i]; #endif } else @@ -201,36 +206,36 @@ int echo_can_monitor_line_spectrum_update(const int16_t amp[], int len) x = 512 - len; for (i = 0; i < x; i++) #if defined(HAVE_FFTW3_H) - in[i][0] = in[in_ptr - x + i][0]; + s->in[i][0] = s->in[s->in_ptr - x + i][0]; #else - in[i].re = in[in_ptr - x + i].re; + s->in[i].re = s->in[s->in_ptr - x + i].re; #endif for (i = x; i < 512; i++) #if defined(HAVE_FFTW3_H) - in[i][0] = amp[i - x]; + s->in[i][0] = amp[i - x]; #else - in[i].re = amp[i - x]; + s->in[i].re = amp[i - x]; #endif } - in_ptr = 0; + s->in_ptr = 0; #if defined(HAVE_FFTW3_H) - fftw_execute(p); + fftw_execute(s->p); #else - fftw_one(p, in, out); + fftw_one(s->p, s->in, s->out); #endif - if (spec_re) - delete spec_re; - canvas_spec->current(canvas_spec); + if (s->spec_re) + delete s->spec_re; + s->canvas_spec->current(s->canvas_spec); for (i = 0; i < 512; i++) { - spec_re_plot[2*i] = i*4000.0/512.0; + s->spec_re_plot[2*i] = i*4000.0/512.0; #if defined(HAVE_FFTW3_H) - spec_re_plot[2*i + 1] = 20.0*log10(sqrt(out[i][0]*out[i][0] + out[i][1]*out[i][1])/(256.0*32768)) + 3.14; + s->spec_re_plot[2*i + 1] = 20.0*log10(sqrt(s->out[i][0]*s->out[i][0] + s->out[i][1]*s->out[i][1])/(256.0*32768)) + 3.14; #else - spec_re_plot[2*i + 1] = 20.0*log10(sqrt(out[i].re*out[i].re + out[i].im*out[i].im)/(256.0*32768)) + 3.14; + s->spec_re_plot[2*i + 1] = 20.0*log10(sqrt(s->out[i].re*s->out[i].re + s->out[i].im*s->out[i].im)/(256.0*32768)) + 3.14; #endif } - spec_re = new Ca_Line(512, spec_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); + s->spec_re = new Ca_Line(512, s->spec_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); Fl::check(); return 0; } @@ -243,167 +248,170 @@ int start_echo_can_monitor(int len) float y; int i; - w = new Fl_Double_Window(850, 400, "Echo canceller monitor"); + s->w = new Fl_Double_Window(850, 400, "Echo canceller monitor"); - c_spec = new Fl_Group(0, 0, 380, 400); - c_spec->box(FL_DOWN_BOX); - c_spec->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); + s->c_spec = new Fl_Group(0, 0, 380, 400); + s->c_spec->box(FL_DOWN_BOX); + s->c_spec->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); - canvas_spec = new Ca_Canvas(60, 30, 300, 300, "Spectrum"); - canvas_spec->box(FL_PLASTIC_DOWN_BOX); - canvas_spec->color(7); - canvas_spec->align(FL_ALIGN_TOP); - canvas_spec->border(15); + s->canvas_spec = new Ca_Canvas(60, 30, 300, 300, "Spectrum"); + s->canvas_spec->box(FL_PLASTIC_DOWN_BOX); + s->canvas_spec->color(7); + s->canvas_spec->align(FL_ALIGN_TOP); + s->canvas_spec->border(15); - spec_freq = new Ca_X_Axis(65, 330, 290, 30, "Freq (Hz)"); - spec_freq->align(FL_ALIGN_BOTTOM); - spec_freq->minimum(0); - spec_freq->maximum(4000); - spec_freq->label_format("%g"); - spec_freq->minor_grid_color(fl_gray_ramp(20)); - spec_freq->major_grid_color(fl_gray_ramp(15)); - spec_freq->label_grid_color(fl_gray_ramp(10)); - spec_freq->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - spec_freq->minor_grid_style(FL_DOT); - spec_freq->major_step(5); - spec_freq->label_step(1); - spec_freq->axis_color(FL_BLACK); - spec_freq->axis_align(CA_BOTTOM | CA_LINE); + s->spec_freq = new Ca_X_Axis(65, 330, 290, 30, "Freq (Hz)"); + s->spec_freq->align(FL_ALIGN_BOTTOM); + s->spec_freq->minimum(0); + s->spec_freq->maximum(4000); + s->spec_freq->label_format("%g"); + s->spec_freq->minor_grid_color(fl_gray_ramp(20)); + s->spec_freq->major_grid_color(fl_gray_ramp(15)); + s->spec_freq->label_grid_color(fl_gray_ramp(10)); + s->spec_freq->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->spec_freq->minor_grid_style(FL_DOT); + s->spec_freq->major_step(5); + s->spec_freq->label_step(1); + s->spec_freq->axis_color(FL_BLACK); + s->spec_freq->axis_align(CA_BOTTOM | CA_LINE); - spec_amp = new Ca_Y_Axis(20, 35, 40, 290, "Amp (dBmO)"); - spec_amp->align(FL_ALIGN_LEFT); - spec_amp->minimum(-80.0); - spec_amp->maximum(10.0); - spec_amp->minor_grid_color(fl_gray_ramp(20)); - spec_amp->major_grid_color(fl_gray_ramp(15)); - spec_amp->label_grid_color(fl_gray_ramp(10)); - //spec_amp->grid_visible(CA_MINOR_TICK | CA_MAJOR_TICK | CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - spec_amp->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - spec_amp->minor_grid_style(FL_DOT); - spec_amp->major_step(5); - spec_amp->label_step(1); - spec_amp->axis_color(FL_BLACK); + s->spec_amp = new Ca_Y_Axis(20, 35, 40, 290, "Amp (dBmO)"); + s->spec_amp->align(FL_ALIGN_LEFT); + s->spec_amp->minimum(-80.0); + s->spec_amp->maximum(10.0); + s->spec_amp->minor_grid_color(fl_gray_ramp(20)); + s->spec_amp->major_grid_color(fl_gray_ramp(15)); + s->spec_amp->label_grid_color(fl_gray_ramp(10)); + //s->spec_amp->grid_visible(CA_MINOR_TICK | CA_MAJOR_TICK | CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->spec_amp->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->spec_amp->minor_grid_style(FL_DOT); + s->spec_amp->major_step(5); + s->spec_amp->label_step(1); + s->spec_amp->axis_color(FL_BLACK); - spec_amp->current(); + s->spec_amp->current(); + s->spec_re = NULL; - c_spec->end(); + s->c_spec->end(); - c_right = new Fl_Group(440, 0, 465, 405); + s->c_right = new Fl_Group(440, 0, 465, 405); - c_can = new Fl_Group(380, 0, 415, 200); - c_can->box(FL_DOWN_BOX); - c_can->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); - c_can->current(); + s->c_can = new Fl_Group(380, 0, 415, 200); + s->c_can->box(FL_DOWN_BOX); + s->c_can->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); + s->c_can->current(); - canvas_can = new Ca_Canvas(460, 35, 300, 100, "Canceller coefficients"); - canvas_can->box(FL_PLASTIC_DOWN_BOX); - canvas_can->color(7); - canvas_can->align(FL_ALIGN_TOP); - Fl_Group::current()->resizable(canvas_can); - canvas_can->border(15); + s->canvas_can = new Ca_Canvas(460, 35, 300, 100, "Canceller coefficients"); + s->canvas_can->box(FL_PLASTIC_DOWN_BOX); + s->canvas_can->color(7); + s->canvas_can->align(FL_ALIGN_TOP); + Fl_Group::current()->resizable(s->canvas_can); + s->canvas_can->border(15); - can_x = new Ca_X_Axis(465, 135, 290, 30, "Tap"); - can_x->align(FL_ALIGN_BOTTOM); - can_x->minimum(0.0); - can_x->maximum((float) len); - can_x->label_format("%g"); - can_x->minor_grid_color(fl_gray_ramp(20)); - can_x->major_grid_color(fl_gray_ramp(15)); - can_x->label_grid_color(fl_gray_ramp(10)); - can_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - can_x->minor_grid_style(FL_DOT); - can_x->major_step(5); - can_x->label_step(1); - can_x->axis_align(CA_BOTTOM | CA_LINE); - can_x->axis_color(FL_BLACK); - can_x->current(); + s->can_x = new Ca_X_Axis(465, 135, 290, 30, "Tap"); + s->can_x->align(FL_ALIGN_BOTTOM); + s->can_x->minimum(0.0); + s->can_x->maximum((float) len); + s->can_x->label_format("%g"); + s->can_x->minor_grid_color(fl_gray_ramp(20)); + s->can_x->major_grid_color(fl_gray_ramp(15)); + s->can_x->label_grid_color(fl_gray_ramp(10)); + s->can_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->can_x->minor_grid_style(FL_DOT); + s->can_x->major_step(5); + s->can_x->label_step(1); + s->can_x->axis_align(CA_BOTTOM | CA_LINE); + s->can_x->axis_color(FL_BLACK); + s->can_x->current(); - can_y = new Ca_Y_Axis(420, 40, 40, 90, "Amp"); - can_y->align(FL_ALIGN_LEFT); - can_y->minimum(-0.1); - can_y->maximum(0.1); - can_y->minor_grid_color(fl_gray_ramp(20)); - can_y->major_grid_color(fl_gray_ramp(15)); - can_y->label_grid_color(fl_gray_ramp(10)); - can_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - can_y->minor_grid_style(FL_DOT); - can_y->major_step(5); - can_y->label_step(1); - can_y->axis_color(FL_BLACK); - can_y->current(); + s->can_y = new Ca_Y_Axis(420, 40, 40, 90, "Amp"); + s->can_y->align(FL_ALIGN_LEFT); + s->can_y->minimum(-0.1); + s->can_y->maximum(0.1); + s->can_y->minor_grid_color(fl_gray_ramp(20)); + s->can_y->major_grid_color(fl_gray_ramp(15)); + s->can_y->label_grid_color(fl_gray_ramp(10)); + s->can_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->can_y->minor_grid_style(FL_DOT); + s->can_y->major_step(5); + s->can_y->label_step(1); + s->can_y->axis_color(FL_BLACK); + s->can_y->current(); - c_can->end(); + s->c_can->end(); + s->can_re = NULL; - c_line_model = new Fl_Group(380, 200, 415, 200); - c_line_model->box(FL_DOWN_BOX); - c_line_model->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); - c_line_model->current(); + s->c_line_model = new Fl_Group(380, 200, 415, 200); + s->c_line_model->box(FL_DOWN_BOX); + s->c_line_model->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); + s->c_line_model->current(); - canvas_line_model = new Ca_Canvas(460, 235, 300, 100, "Line impulse response model"); - canvas_line_model->box(FL_PLASTIC_DOWN_BOX); - canvas_line_model->color(7); - canvas_line_model->align(FL_ALIGN_TOP); - Fl_Group::current()->resizable(canvas_line_model); - canvas_line_model->border(15); + s->canvas_line_model = new Ca_Canvas(460, 235, 300, 100, "Line impulse response model"); + s->canvas_line_model->box(FL_PLASTIC_DOWN_BOX); + s->canvas_line_model->color(7); + s->canvas_line_model->align(FL_ALIGN_TOP); + Fl_Group::current()->resizable(s->canvas_line_model); + s->canvas_line_model->border(15); - line_model_x = new Ca_X_Axis(465, 335, 290, 30, "Tap"); - line_model_x->align(FL_ALIGN_BOTTOM); - line_model_x->minimum(0.0); - line_model_x->maximum((float) len); - line_model_x->label_format("%g"); - line_model_x->minor_grid_color(fl_gray_ramp(20)); - line_model_x->major_grid_color(fl_gray_ramp(15)); - line_model_x->label_grid_color(fl_gray_ramp(10)); - line_model_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - line_model_x->minor_grid_style(FL_DOT); - line_model_x->major_step(5); - line_model_x->label_step(1); - line_model_x->axis_align(CA_BOTTOM | CA_LINE); - line_model_x->axis_color(FL_BLACK); - line_model_x->current(); + s->line_model_x = new Ca_X_Axis(465, 335, 290, 30, "Tap"); + s->line_model_x->align(FL_ALIGN_BOTTOM); + s->line_model_x->minimum(0.0); + s->line_model_x->maximum((float) len); + s->line_model_x->label_format("%g"); + s->line_model_x->minor_grid_color(fl_gray_ramp(20)); + s->line_model_x->major_grid_color(fl_gray_ramp(15)); + s->line_model_x->label_grid_color(fl_gray_ramp(10)); + s->line_model_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->line_model_x->minor_grid_style(FL_DOT); + s->line_model_x->major_step(5); + s->line_model_x->label_step(1); + s->line_model_x->axis_align(CA_BOTTOM | CA_LINE); + s->line_model_x->axis_color(FL_BLACK); + s->line_model_x->current(); - line_model_y = new Ca_Y_Axis(420, 240, 40, 90, "Amp"); - line_model_y->align(FL_ALIGN_LEFT); - line_model_y->minimum(-0.1); - line_model_y->maximum(0.1); - line_model_y->minor_grid_color(fl_gray_ramp(20)); - line_model_y->major_grid_color(fl_gray_ramp(15)); - line_model_y->label_grid_color(fl_gray_ramp(10)); - line_model_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - line_model_y->minor_grid_style(FL_DOT); - line_model_y->major_step(5); - line_model_y->label_step(1); - line_model_y->axis_color(FL_BLACK); - line_model_y->current(); + s->line_model_y = new Ca_Y_Axis(420, 240, 40, 90, "Amp"); + s->line_model_y->align(FL_ALIGN_LEFT); + s->line_model_y->minimum(-0.1); + s->line_model_y->maximum(0.1); + s->line_model_y->minor_grid_color(fl_gray_ramp(20)); + s->line_model_y->major_grid_color(fl_gray_ramp(15)); + s->line_model_y->label_grid_color(fl_gray_ramp(10)); + s->line_model_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->line_model_y->minor_grid_style(FL_DOT); + s->line_model_y->major_step(5); + s->line_model_y->label_step(1); + s->line_model_y->axis_color(FL_BLACK); + s->line_model_y->current(); - c_line_model->end(); + s->c_line_model->end(); + s->line_model_re = NULL; - audio_meter = new Fl_Audio_Meter(810, 40, 10, 250, ""); - audio_meter->box(FL_PLASTIC_UP_BOX); - audio_meter->type(FL_VERT_AUDIO_METER); + s->audio_meter = new Fl_Audio_Meter(810, 40, 10, 250, ""); + s->audio_meter->box(FL_PLASTIC_UP_BOX); + s->audio_meter->type(FL_VERT_AUDIO_METER); - c_right->end(); + s->c_right->end(); - Fl_Group::current()->resizable(c_right); - w->end(); - w->show(); + Fl_Group::current()->resizable(s->c_right); + s->w->end(); + s->w->show(); #if defined(HAVE_FFTW3_H) - p = fftw_plan_dft_1d(1024, in, out, FFTW_BACKWARD, FFTW_ESTIMATE); + s->p = fftw_plan_dft_1d(1024, s->in, s->out, FFTW_BACKWARD, FFTW_ESTIMATE); for (i = 0; i < 1024; i++) { - in[i][0] = 0.0; - in[i][1] = 0.0; + s->in[i][0] = 0.0; + s->in[i][1] = 0.0; } #else - p = fftw_create_plan(1024, FFTW_BACKWARD, FFTW_ESTIMATE); + s->p = fftw_create_plan(1024, FFTW_BACKWARD, FFTW_ESTIMATE); for (i = 0; i < 1024; i++) { - in[i].re = 0.0; - in[i].im = 0.0; + s->in[i].re = 0.0; + s->in[i].im = 0.0; } #endif - in_ptr = 0; + s->in_ptr = 0; Fl::check(); return 0; diff --git a/libs/spandsp/tests/echo_tests.c b/libs/spandsp/tests/echo_tests.c index 6d67e38e34..06e3ab5418 100644 --- a/libs/spandsp/tests/echo_tests.c +++ b/libs/spandsp/tests/echo_tests.c @@ -25,7 +25,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: echo_tests.c,v 1.35 2008/08/29 09:28:13 steveu Exp $ + * $Id: echo_tests.c,v 1.36 2008/09/04 14:40:05 steveu Exp $ */ /*! \page echo_can_tests_page Line echo cancellation for voice tests @@ -259,6 +259,7 @@ static level_measurement_device_t *level_measurement_device_create(int type) } /*- End of function --------------------------------------------------------*/ +#if 0 static void level_measurement_device_reset(level_measurement_device_t *dev) { int i; @@ -279,6 +280,7 @@ static int level_measurement_device_release(level_measurement_device_t *s) return 0; } /*- End of function --------------------------------------------------------*/ +#endif static float level_measurement_device_get_peak(level_measurement_device_t *dev) { @@ -534,6 +536,7 @@ static int16_t far_noise_signal(void) } /*- End of function --------------------------------------------------------*/ +#if 0 static int16_t local_hoth_noise_signal(void) { static float hoth_noise = 0.0; @@ -542,6 +545,7 @@ static int16_t local_hoth_noise_signal(void) return (int16_t) hoth_noise; } /*- End of function --------------------------------------------------------*/ +#endif static int16_t far_hoth_noise_signal(void) { @@ -1483,7 +1487,7 @@ static int match_test_name(const char *name) } /*- End of function --------------------------------------------------------*/ -static void simulate_ec(const char *argv[], int two_channel_file, int mode) +static void simulate_ec(char *argv[], int two_channel_file, int mode) { echo_can_state_t *ctx; AFfilehandle txfile; diff --git a/libs/spandsp/tests/fax_decode.c b/libs/spandsp/tests/fax_decode.c index fe66e48bd7..93dfc835d1 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.45 2008/08/13 00:11:30 steveu Exp $ + * $Id: fax_decode.c,v 1.48 2008/09/07 12:45:17 steveu Exp $ */ /*! \page fax_decode_page FAX decoder @@ -219,16 +219,16 @@ static void hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok) /* Special conditions */ switch (len) { - case PUTBIT_CARRIER_UP: + case SIG_STATUS_CARRIER_UP: fprintf(stderr, "HDLC carrier up\n"); break; - case PUTBIT_CARRIER_DOWN: + case SIG_STATUS_CARRIER_DOWN: fprintf(stderr, "HDLC carrier down\n"); break; - case PUTBIT_FRAMING_OK: + case SIG_STATUS_FRAMING_OK: fprintf(stderr, "HDLC framing OK\n"); break; - case PUTBIT_ABORT: + case SIG_STATUS_ABORT: /* Just ignore these */ break; default: @@ -331,19 +331,22 @@ static void v21_put_bit(void *user_data, int bit) /* Special conditions */ switch (bit) { - case PUTBIT_TRAINING_FAILED: + case SIG_STATUS_TRAINING_FAILED: fprintf(stderr, "V.21 Training failed\n"); break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_IN_PROGRESS: + fprintf(stderr, "V.21 Training in progress\n"); + break; + case SIG_STATUS_TRAINING_SUCCEEDED: fprintf(stderr, "V.21 Training succeeded\n"); t4_begin(); break; - case PUTBIT_CARRIER_UP: + case SIG_STATUS_CARRIER_UP: fprintf(stderr, "V.21 Carrier up\n"); break; - case PUTBIT_CARRIER_DOWN: + case SIG_STATUS_CARRIER_DOWN: fprintf(stderr, "V.21 Carrier down\n"); - t4_end(); + //t4_end(); break; default: fprintf(stderr, "V.21 Eh!\n"); @@ -364,18 +367,21 @@ static void v17_put_bit(void *user_data, int bit) /* Special conditions */ switch (bit) { - case PUTBIT_TRAINING_FAILED: + case SIG_STATUS_TRAINING_FAILED: fprintf(stderr, "V.17 Training failed\n"); break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_IN_PROGRESS: + fprintf(stderr, "V.17 Training in progress\n"); + break; + case SIG_STATUS_TRAINING_SUCCEEDED: fprintf(stderr, "V.17 Training succeeded\n"); fast_trained = FAX_V17_RX; t4_begin(); break; - case PUTBIT_CARRIER_UP: + case SIG_STATUS_CARRIER_UP: fprintf(stderr, "V.17 Carrier up\n"); break; - case PUTBIT_CARRIER_DOWN: + case SIG_STATUS_CARRIER_DOWN: fprintf(stderr, "V.17 Carrier down\n"); t4_end(); if (fast_trained == FAX_V17_RX) @@ -410,18 +416,21 @@ static void v29_put_bit(void *user_data, int bit) /* Special conditions */ switch (bit) { - case PUTBIT_TRAINING_FAILED: + case SIG_STATUS_TRAINING_FAILED: //fprintf(stderr, "V.29 Training failed\n"); break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_IN_PROGRESS: + fprintf(stderr, "V.29 Training in progress\n"); + break; + case SIG_STATUS_TRAINING_SUCCEEDED: fprintf(stderr, "V.29 Training succeeded\n"); fast_trained = FAX_V29_RX; t4_begin(); break; - case PUTBIT_CARRIER_UP: + case SIG_STATUS_CARRIER_UP: //fprintf(stderr, "V.29 Carrier up\n"); break; - case PUTBIT_CARRIER_DOWN: + case SIG_STATUS_CARRIER_DOWN: //fprintf(stderr, "V.29 Carrier down\n"); t4_end(); if (fast_trained == FAX_V29_RX) @@ -456,19 +465,23 @@ static void v27ter_put_bit(void *user_data, int bit) /* Special conditions */ switch (bit) { - case PUTBIT_TRAINING_FAILED: + case SIG_STATUS_TRAINING_FAILED: //fprintf(stderr, "V.27ter Training failed\n"); break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_IN_PROGRESS: + fprintf(stderr, "V.27ter Training in progress\n"); + break; + case SIG_STATUS_TRAINING_SUCCEEDED: fprintf(stderr, "V.27ter Training succeeded\n"); fast_trained = FAX_V27TER_RX; t4_begin(); break; - case PUTBIT_CARRIER_UP: + case SIG_STATUS_CARRIER_UP: //fprintf(stderr, "V.27ter Carrier up\n"); break; - case PUTBIT_CARRIER_DOWN: + case SIG_STATUS_CARRIER_DOWN: //fprintf(stderr, "V.27ter Carrier down\n"); + t4_end(); if (fast_trained == FAX_V27TER_RX) fast_trained = FAX_NONE; break; diff --git a/libs/spandsp/tests/fax_tester.c b/libs/spandsp/tests/fax_tester.c index dd56260c9b..4f54f80e54 100644 --- a/libs/spandsp/tests/fax_tester.c +++ b/libs/spandsp/tests/fax_tester.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_tester.c,v 1.13 2008/08/13 00:11:30 steveu Exp $ + * $Id: fax_tester.c,v 1.16 2008/09/09 14:05:55 steveu Exp $ */ /*! \file */ @@ -146,18 +146,12 @@ static int modem_tx_status(void *user_data, int status) faxtester_state_t *s; s = (faxtester_state_t *) user_data; + printf("Tx status is %s (%d)\n", signal_status_to_str(status), status); switch (status) { - case MODEM_TX_STATUS_DATA_EXHAUSTED: - span_log(&s->logging, SPAN_LOG_FLOW, "Tx data exhausted\n"); - break; - case MODEM_TX_STATUS_SHUTDOWN_COMPLETE: - span_log(&s->logging, SPAN_LOG_FLOW, "Tx shutdown complete\n"); + case SIG_STATUS_SHUTDOWN_COMPLETE: front_end_step_complete(s); break; - default: - span_log(&s->logging, SPAN_LOG_FLOW, "Tx status is %d\n", status); - break; } return 0; } @@ -202,7 +196,7 @@ static int non_ecm_get_bit(void *user_data) if (s->image_ptr >= s->image_len) { s->image_buffer = NULL; - return PUTBIT_END_OF_DATA; + return SIG_STATUS_END_OF_DATA; } s->image_bit_ptr = 8; s->image_ptr++; @@ -241,25 +235,20 @@ static void non_ecm_rx_status(void *user_data, int status) faxtester_state_t *s; s = (faxtester_state_t *) user_data; + span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier status is %s (%d)\n", signal_status_to_str(status), status); switch (status) { - case PUTBIT_TRAINING_IN_PROGRESS: - break; - case PUTBIT_TRAINING_FAILED: - span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier training failed\n"); + case SIG_STATUS_TRAINING_FAILED: s->modems.rx_trained = FALSE; break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_SUCCEEDED: /* The modem is now trained */ - span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier trained\n"); s->modems.rx_trained = TRUE; break; - case PUTBIT_CARRIER_UP: - span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier up\n"); + case SIG_STATUS_CARRIER_UP: s->modems.rx_signal_present = TRUE; break; - case PUTBIT_CARRIER_DOWN: - span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier down\n"); + case SIG_STATUS_CARRIER_DOWN: if (s->modems.rx_trained) { if (s->real_time_frame_handler) @@ -268,9 +257,6 @@ static void non_ecm_rx_status(void *user_data, int status) s->modems.rx_signal_present = FALSE; s->modems.rx_trained = FALSE; break; - default: - span_log(&s->logging, SPAN_LOG_WARNING, "Unexpected non-ECM rx status - %d!\n", status); - break; } } /*- End of function --------------------------------------------------------*/ @@ -293,37 +279,23 @@ static void hdlc_rx_status(void *user_data, int status) faxtester_state_t *s; s = (faxtester_state_t *) user_data; + fprintf(stderr, "HDLC carrier status is %s (%d)\n", signal_status_to_str(status), status); switch (status) { - case PUTBIT_TRAINING_IN_PROGRESS: - break; - case PUTBIT_TRAINING_FAILED: - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier training failed\n"); + case SIG_STATUS_TRAINING_FAILED: s->modems.rx_trained = FALSE; break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_SUCCEEDED: /* The modem is now trained */ - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier trained\n"); s->modems.rx_trained = TRUE; break; - case PUTBIT_CARRIER_UP: - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier up\n"); + case SIG_STATUS_CARRIER_UP: s->modems.rx_signal_present = TRUE; break; - case PUTBIT_CARRIER_DOWN: - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier down\n"); + case SIG_STATUS_CARRIER_DOWN: s->modems.rx_signal_present = FALSE; s->modems.rx_trained = FALSE; break; - case PUTBIT_FRAMING_OK: - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC framing OK\n"); - break; - case PUTBIT_ABORT: - /* Just ignore these */ - break; - default: - span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected HDLC special length - %d!\n", status); - break; } } /*- End of function --------------------------------------------------------*/ diff --git a/libs/spandsp/tests/fax_tests.c b/libs/spandsp/tests/fax_tests.c index 4bf923b633..b419d58e08 100644 --- a/libs/spandsp/tests/fax_tests.c +++ b/libs/spandsp/tests/fax_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: fax_tests.c,v 1.95 2008/08/29 09:28:13 steveu Exp $ + * $Id: fax_tests.c,v 1.96 2008/09/09 14:05:55 steveu Exp $ */ /*! \page fax_tests_page FAX tests @@ -167,7 +167,8 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) printf("%d: Phase E: longest bad row run %d\n", i, t.longest_bad_row_run); printf("%d: Phase E: coding method %s\n", i, t4_encoding_to_str(t.encoding)); printf("%d: Phase E: image size %d bytes\n", i, t.image_size); - //printf("%d: Phase E: local ident '%s'\n", i, info->ident); + if ((u = t30_get_tx_ident(s))) + printf("%d: Phase E: local ident '%s'\n", i, u); if ((u = t30_get_rx_ident(s))) printf("%d: Phase E: remote ident '%s'\n", i, u); if ((u = t30_get_rx_country(s))) diff --git a/libs/spandsp/tests/fsk_tests.c b/libs/spandsp/tests/fsk_tests.c index 833fb9a864..e11ba327ed 100644 --- a/libs/spandsp/tests/fsk_tests.c +++ b/libs/spandsp/tests/fsk_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: fsk_tests.c,v 1.48 2008/08/29 09:28:13 steveu Exp $ + * $Id: fsk_tests.c,v 1.50 2008/09/07 12:45:17 steveu Exp $ */ /*! \page fsk_tests_page FSK modem tests @@ -67,43 +67,14 @@ int cutoff_test_carrier = FALSE; static int rx_status(void *user_data, int status) { - printf("FSK rx status is %d\n", status); - switch (status) - { - case PUTBIT_TRAINING_FAILED: - printf("Training failed\n"); - break; - case PUTBIT_TRAINING_SUCCEEDED: - printf("Training succeeded\n"); - break; - case PUTBIT_CARRIER_UP: - printf("Carrier up\n"); - break; - case PUTBIT_CARRIER_DOWN: - printf("Carrier down\n"); - break; - default: - printf("Eh! - %d\n", status); - break; - } + printf("FSK rx status is %s (%d)\n", signal_status_to_str(status), status); return 0; } /*- End of function --------------------------------------------------------*/ static int tx_status(void *user_data, int status) { - switch (status) - { - case MODEM_TX_STATUS_DATA_EXHAUSTED: - printf("FSK tx data exhausted\n"); - break; - case MODEM_TX_STATUS_SHUTDOWN_COMPLETE: - printf("FSK tx shutdown complete\n"); - break; - default: - printf("FSK tx status is %d\n", status); - break; - } + printf("FSK tx status is %s (%d)\n", signal_status_to_str(status), status); return 0; } /*- End of function --------------------------------------------------------*/ @@ -122,26 +93,15 @@ static void put_bit(void *user_data, int bit) static int cutoff_test_rx_status(void *user_data, int status) { - printf("FSK rx status is %d\n", status); + printf("FSK rx status is %s (%d)\n", signal_status_to_str(status), status); switch (status) { - case PUTBIT_TRAINING_FAILED: - printf("Training failed\n"); - break; - case PUTBIT_TRAINING_SUCCEEDED: - printf("Training succeeded\n"); - break; - case PUTBIT_CARRIER_UP: - //printf("Carrier up\n"); + case SIG_STATUS_CARRIER_UP: cutoff_test_carrier = TRUE; break; - case PUTBIT_CARRIER_DOWN: - //printf("Carrier down\n"); + case SIG_STATUS_CARRIER_DOWN: cutoff_test_carrier = FALSE; break; - default: - printf("Eh! - %d\n", status); - break; } return 0; } diff --git a/libs/spandsp/tests/g168_tests.c b/libs/spandsp/tests/g168_tests.c index 154892c8cd..f95acfe827 100644 --- a/libs/spandsp/tests/g168_tests.c +++ b/libs/spandsp/tests/g168_tests.c @@ -24,7 +24,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: g168_tests.c,v 1.16 2008/08/29 09:28:13 steveu Exp $ + * $Id: g168_tests.c,v 1.18 2008/09/04 14:40:05 steveu Exp $ */ #if defined(HAVE_CONFIG_H) @@ -55,7 +55,7 @@ typedef struct signal_source_t local_css; signal_source_t far_css; -AFfilehandle afOpenFile_telephony_read(const char *name, int channels) +static AFfilehandle afOpenFile_telephony_read(const char *name, int channels) { float x; AFfilehandle handle; @@ -85,7 +85,8 @@ AFfilehandle afOpenFile_telephony_read(const char *name, int channels) } /*- End of function --------------------------------------------------------*/ -AFfilehandle afOpenFile_telephony_write(const char *name, int channels) +#if 0 +static AFfilehandle afOpenFile_telephony_write(const char *name, int channels) { AFfilesetup setup; AFfilehandle handle; @@ -110,6 +111,7 @@ AFfilehandle afOpenFile_telephony_write(const char *name, int channels) return handle; } /*- End of function --------------------------------------------------------*/ +#endif static void signal_load(signal_source_t *sig, const char *name) { @@ -367,6 +369,8 @@ int main(int argc, char *argv[]) printf("\n"); for (i = 0; i < (int) (sizeof(css_c1)/sizeof(css_c3[0])); i++) printf("%d\n", css_c3[i]); + signal_free(&local_css); + signal_free(&far_css); return 0; } /*- End of function --------------------------------------------------------*/ diff --git a/libs/spandsp/tests/hdlc_tests.c b/libs/spandsp/tests/hdlc_tests.c index f1dd309c08..9df26737f2 100644 --- a/libs/spandsp/tests/hdlc_tests.c +++ b/libs/spandsp/tests/hdlc_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: hdlc_tests.c,v 1.43 2008/05/13 13:17:25 steveu Exp $ + * $Id: hdlc_tests.c,v 1.46 2008/09/07 12:55:13 steveu Exp $ */ /*! \file */ @@ -39,6 +39,7 @@ using both 16 and 32 bit CRCs. #include #include +#include #include #include "spandsp.h" @@ -92,43 +93,15 @@ static void frame_handler(void *user_data, const uint8_t *pkt, int len, int ok) if (len < 0) { /* Special conditions */ + printf("HDLC rx status is %s (%d)\n", signal_status_to_str(len), len); switch (len) { - case PUTBIT_TRAINING_IN_PROGRESS: - printf("Training in progress\n"); - break; - case PUTBIT_TRAINING_FAILED: - printf("Training failed\n"); - break; - case PUTBIT_TRAINING_SUCCEEDED: - printf("Training succeeded\n"); - break; - case PUTBIT_CARRIER_UP: - printf("Carrier up\n"); - break; - case PUTBIT_CARRIER_DOWN: - printf("Carrier down\n"); - break; - case PUTBIT_FRAMING_OK: + case SIG_STATUS_FRAMING_OK: framing_ok_reported = TRUE; framing_ok_reports++; - //printf("Framing OK\n"); break; - case PUTBIT_END_OF_DATA: - printf("End of data\n"); - break; - case PUTBIT_ABORT: + case SIG_STATUS_ABORT: abort_reported = TRUE; - //printf("Abort\n"); - break; - case PUTBIT_BREAK: - printf("Break\n"); - break; - case PUTBIT_OCTET_REPORT: - printf("Octet report\n"); - break; - default: - printf("Eh!\n"); break; } return; @@ -779,7 +752,7 @@ static int test_hdlc_octet_count_handling(void) /*- End of function --------------------------------------------------------*/ #endif -int main(int argc, char *argv[]) +static void hdlc_tests(void) { printf("HDLC module tests\n"); @@ -811,6 +784,76 @@ int main(int argc, char *argv[]) } #endif printf("Tests passed.\n"); +} +/*- End of function --------------------------------------------------------*/ + +static void decode_handler(void *user_data, const uint8_t *pkt, int len, int ok) +{ + if (len < 0) + { + /* Special conditions */ + printf("HDLC rx status is %s (%d)\n", signal_status_to_str(len), len); + return; + } + if (ok) + { + printf("Good frame, len = %d\n", len); + } + else + { + printf("Bad frame, len = %d\n", len); + } +} +/*- End of function --------------------------------------------------------*/ + +static void decode_bitstream(const char *in_file_name) +{ + char buf[1024]; + int bit; + hdlc_rx_state_t rx; + FILE *in; + + if ((in = fopen(in_file_name, "r")) == NULL) + { + fprintf(stderr, "Failed to open '%s'\n", in_file_name); + exit(2); + } + + hdlc_rx_init(&rx, TRUE, TRUE, 2, decode_handler, NULL); + while (fgets(buf, 1024, in)) + { + if (sscanf(buf, "Rx bit %*d - %d", &bit) == 1) + { + hdlc_rx_put_bit(&rx, bit); + } + } + fclose(in); +} +/*- End of function --------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + int opt; + const char *in_file_name; + + in_file_name = NULL; + while ((opt = getopt(argc, argv, "d:")) != -1) + { + switch (opt) + { + case 'd': + in_file_name = optarg; + break; + default: + //usage(); + exit(2); + break; + } + } + if (in_file_name) + decode_bitstream(in_file_name); + else + hdlc_tests(); return 0; } /*- End of function --------------------------------------------------------*/ diff --git a/libs/spandsp/tests/line_model_monitor.cpp b/libs/spandsp/tests/line_model_monitor.cpp index 7cf3ab6eee..77454727d4 100644 --- a/libs/spandsp/tests/line_model_monitor.cpp +++ b/libs/spandsp/tests/line_model_monitor.cpp @@ -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_monitor.cpp,v 1.4 2008/05/27 15:08:21 steveu Exp $ + * $Id: line_model_monitor.cpp,v 1.5 2008/09/08 16:10:41 steveu Exp $ */ #ifdef HAVE_CONFIG_H @@ -56,44 +56,49 @@ #include "spandsp.h" #include "line_model_monitor.h" -Fl_Double_Window *w; +struct line_model_monitor_s +{ + Fl_Double_Window *w; -Fl_Audio_Meter *audio_meter; + Fl_Audio_Meter *audio_meter; -Fl_Group *c_spec; -Fl_Group *c_right; -Fl_Group *c_can; -Fl_Group *c_line_model; + Fl_Group *c_spec; + Fl_Group *c_right; + Fl_Group *c_can; + Fl_Group *c_line_model; -Ca_Canvas *canvas_spec; -Ca_X_Axis *spec_freq; -Ca_Y_Axis *spec_amp; -Ca_Line *spec_re = NULL; -double spec_re_plot[2*512]; + Ca_Canvas *canvas_spec; + Ca_X_Axis *spec_freq; + Ca_Y_Axis *spec_amp; + Ca_Line *spec_re; + double spec_re_plot[2*512]; -Ca_Canvas *canvas_can; -Ca_X_Axis *can_x; -Ca_Y_Axis *can_y; -Ca_Line *can_re = NULL; -double can_re_plot[512]; + Ca_Canvas *canvas_can; + Ca_X_Axis *can_x; + Ca_Y_Axis *can_y; + Ca_Line *can_re; + double can_re_plot[512]; -Ca_Canvas *canvas_line_model; -Ca_X_Axis *line_model_x; -Ca_Y_Axis *line_model_y; -Ca_Line *line_model_re = NULL; -double line_model_re_plot[512]; + Ca_Canvas *canvas_line_model; + Ca_X_Axis *line_model_x; + Ca_Y_Axis *line_model_y; + Ca_Line *line_model_re; + double line_model_re_plot[512]; + + int in_ptr; +#if defined(HAVE_FFTW3_H) + double in[1024][2]; + double out[1024][2]; +#else + fftw_complex in[1024]; + fftw_complex out[1024]; +#endif + fftw_plan p; +}; static int skip = 0; - -int in_ptr; -#if defined(HAVE_FFTW3_H) -double in[1024][2]; -double out[1024][2]; -#else -fftw_complex in[1024]; -fftw_complex out[1024]; -#endif -fftw_plan p; +static struct line_model_monitor_s model; +static struct line_model_monitor_s *s = &model; int line_model_monitor_can_update(const float *coeffs, int len) { @@ -101,25 +106,25 @@ int line_model_monitor_can_update(const float *coeffs, int len) float min; float max; - if (can_re) - delete can_re; + if (s->can_re) + delete s->can_re; - canvas_can->current(canvas_can); + s->canvas_can->current(s->canvas_can); i = 0; min = coeffs[i]; max = coeffs[i]; for (i = 0; i < len; i++) { - can_re_plot[2*i] = i; - can_re_plot[2*i + 1] = coeffs[i]; + s->can_re_plot[2*i] = i; + s->can_re_plot[2*i + 1] = coeffs[i]; if (min > coeffs[i]) min = coeffs[i]; if (max < coeffs[i]) max = coeffs[i]; } - can_y->maximum((max == min) ? max + 0.2 : max); - can_y->minimum(min); - can_re = new Ca_Line(len, can_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); + s->can_y->maximum((max == min) ? max + 0.2 : max); + s->can_y->minimum(min); + s->can_re = new Ca_Line(len, s->can_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); if (++skip >= 100) { skip = 0; @@ -135,25 +140,25 @@ int line_model_monitor_line_model_update(const float *coeffs, int len) float min; float max; - if (line_model_re) - delete line_model_re; + if (s->line_model_re) + delete s->line_model_re; - canvas_line_model->current(canvas_line_model); + s->canvas_line_model->current(s->canvas_line_model); i = 0; min = coeffs[i]; max = coeffs[i]; for (i = 0; i < len; i++) { - line_model_re_plot[2*i] = i; - line_model_re_plot[2*i + 1] = coeffs[i]; + s->line_model_re_plot[2*i] = i; + s->line_model_re_plot[2*i + 1] = coeffs[i]; if (min > coeffs[i]) min = coeffs[i]; if (max < coeffs[i]) max = coeffs[i]; } - line_model_y->maximum((max == min) ? max + 0.2 : max); - line_model_y->minimum(min); - line_model_re = new Ca_Line(len, line_model_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); + s->line_model_y->maximum((max == min) ? max + 0.2 : max); + s->line_model_y->minimum(min); + s->line_model_re = new Ca_Line(len, s->line_model_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); if (++skip >= 100) { skip = 0; @@ -169,18 +174,18 @@ int line_model_monitor_line_spectrum_update(const int16_t amp[], int len) int x; for (i = 0; i < len; i++) - audio_meter->sample(amp[i]/32768.0); + s->audio_meter->sample(amp[i]/32768.0); - if (in_ptr + len < 512) + if (s->in_ptr + len < 512) { /* Just add this fragment to the buffer. */ for (i = 0; i < len; i++) #if defined(HAVE_FFTW3_H) - in[in_ptr + i][0] = amp[i]; + s->in[s->in_ptr + i][0] = amp[i]; #else - in[in_ptr + i].re = amp[i]; + s->in[s->in_ptr + i].re = amp[i]; #endif - in_ptr += len; + s->in_ptr += len; return 0; } if (len >= 512) @@ -190,9 +195,9 @@ int line_model_monitor_line_spectrum_update(const int16_t amp[], int len) x = len - 512; for (i = 0; i < 512; i++) #if defined(HAVE_FFTW3_H) - in[i][0] = amp[x + i]; + s->in[i][0] = amp[x + i]; #else - in[i].re = amp[x + i]; + s->in[i].re = amp[x + i]; #endif } else @@ -201,36 +206,36 @@ int line_model_monitor_line_spectrum_update(const int16_t amp[], int len) x = 512 - len; for (i = 0; i < x; i++) #if defined(HAVE_FFTW3_H) - in[i][0] = in[in_ptr - x + i][0]; + s->in[i][0] = s->in[s->in_ptr - x + i][0]; #else - in[i].re = in[in_ptr - x + i].re; + s->in[i].re = s->in[s->in_ptr - x + i].re; #endif for (i = x; i < 512; i++) #if defined(HAVE_FFTW3_H) - in[i][0] = amp[i - x]; + s->in[i][0] = amp[i - x]; #else - in[i].re = amp[i - x]; + s->in[i].re = amp[i - x]; #endif } - in_ptr = 0; + s->in_ptr = 0; #if defined(HAVE_FFTW3_H) - fftw_execute(p); + fftw_execute(s->p); #else - fftw_one(p, in, out); + fftw_one(s->p, s->in, s->out); #endif - if (spec_re) - delete spec_re; - canvas_spec->current(canvas_spec); + if (s->spec_re) + delete s->spec_re; + s->canvas_spec->current(s->canvas_spec); for (i = 0; i < 512; i++) { - spec_re_plot[2*i] = i*4000.0/512.0; + s->spec_re_plot[2*i] = i*4000.0/512.0; #if defined(HAVE_FFTW3_H) - spec_re_plot[2*i + 1] = 20.0*log10(sqrt(out[i][0]*out[i][0] + out[i][1]*out[i][1])/(256.0*32768)) + 3.14; + s->spec_re_plot[2*i + 1] = 20.0*log10(sqrt(s->out[i][0]*s->out[i][0] + s->out[i][1]*s->out[i][1])/(256.0*32768)) + 3.14; #else - spec_re_plot[2*i + 1] = 20.0*log10(sqrt(out[i].re*out[i].re + out[i].im*out[i].im)/(256.0*32768)) + 3.14; + s->spec_re_plot[2*i + 1] = 20.0*log10(sqrt(s->out[i].re*s->out[i].re + s->out[i].im*s->out[i].im)/(256.0*32768)) + 3.14; #endif } - spec_re = new Ca_Line(512, spec_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); + s->spec_re = new Ca_Line(512, s->spec_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); Fl::check(); return 0; } @@ -243,167 +248,171 @@ int start_line_model_monitor(int len) float y; int i; - w = new Fl_Double_Window(850, 400, "Telephone line model monitor"); + s->w = new Fl_Double_Window(850, 400, "Telephone line model monitor"); - c_spec = new Fl_Group(0, 0, 380, 400); - c_spec->box(FL_DOWN_BOX); - c_spec->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); + s->c_spec = new Fl_Group(0, 0, 380, 400); + s->c_spec->box(FL_DOWN_BOX); + s->c_spec->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); - canvas_spec = new Ca_Canvas(60, 30, 300, 300, "Spectrum"); - canvas_spec->box(FL_PLASTIC_DOWN_BOX); - canvas_spec->color(7); - canvas_spec->align(FL_ALIGN_TOP); - canvas_spec->border(15); + s->canvas_spec = new Ca_Canvas(60, 30, 300, 300, "Spectrum"); + s->canvas_spec->box(FL_PLASTIC_DOWN_BOX); + s->canvas_spec->color(7); + s->canvas_spec->align(FL_ALIGN_TOP); + s->canvas_spec->border(15); - spec_freq = new Ca_X_Axis(65, 330, 290, 30, "Freq (Hz)"); - spec_freq->align(FL_ALIGN_BOTTOM); - spec_freq->minimum(0); - spec_freq->maximum(4000); - spec_freq->label_format("%g"); - spec_freq->minor_grid_color(fl_gray_ramp(20)); - spec_freq->major_grid_color(fl_gray_ramp(15)); - spec_freq->label_grid_color(fl_gray_ramp(10)); - spec_freq->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - spec_freq->minor_grid_style(FL_DOT); - spec_freq->major_step(5); - spec_freq->label_step(1); - spec_freq->axis_color(FL_BLACK); - spec_freq->axis_align(CA_BOTTOM | CA_LINE); + s->spec_freq = new Ca_X_Axis(65, 330, 290, 30, "Freq (Hz)"); + s->spec_freq->align(FL_ALIGN_BOTTOM); + s->spec_freq->minimum(0); + s->spec_freq->maximum(4000); + s->spec_freq->label_format("%g"); + s->spec_freq->minor_grid_color(fl_gray_ramp(20)); + s->spec_freq->major_grid_color(fl_gray_ramp(15)); + s->spec_freq->label_grid_color(fl_gray_ramp(10)); + s->spec_freq->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->spec_freq->minor_grid_style(FL_DOT); + s->spec_freq->major_step(5); + s->spec_freq->label_step(1); + s->spec_freq->axis_color(FL_BLACK); + s->spec_freq->axis_align(CA_BOTTOM | CA_LINE); - spec_amp = new Ca_Y_Axis(20, 35, 40, 290, "Amp (dBmO)"); - spec_amp->align(FL_ALIGN_LEFT); - spec_amp->minimum(-80.0); - spec_amp->maximum(10.0); - spec_amp->minor_grid_color(fl_gray_ramp(20)); - spec_amp->major_grid_color(fl_gray_ramp(15)); - spec_amp->label_grid_color(fl_gray_ramp(10)); - //spec_amp->grid_visible(CA_MINOR_TICK | CA_MAJOR_TICK | CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - spec_amp->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - spec_amp->minor_grid_style(FL_DOT); - spec_amp->major_step(5); - spec_amp->label_step(1); - spec_amp->axis_color(FL_BLACK); + s->spec_amp = new Ca_Y_Axis(20, 35, 40, 290, "Amp (dBmO)"); + s->spec_amp->align(FL_ALIGN_LEFT); + s->spec_amp->minimum(-80.0); + s->spec_amp->maximum(10.0); + s->spec_amp->minor_grid_color(fl_gray_ramp(20)); + s->spec_amp->major_grid_color(fl_gray_ramp(15)); + s->spec_amp->label_grid_color(fl_gray_ramp(10)); + //s->spec_amp->grid_visible(CA_MINOR_TICK | CA_MAJOR_TICK | CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->spec_amp->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->spec_amp->minor_grid_style(FL_DOT); + s->spec_amp->major_step(5); + s->spec_amp->label_step(1); + s->spec_amp->axis_color(FL_BLACK); - spec_amp->current(); + s->spec_amp->current(); + s->spec_re = NULL; - c_spec->end(); + s->c_spec->end(); - c_right = new Fl_Group(440, 0, 465, 405); + s->c_right = new Fl_Group(440, 0, 465, 405); - c_can = new Fl_Group(380, 0, 415, 200); - c_can->box(FL_DOWN_BOX); - c_can->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); - c_can->current(); + s->c_can = new Fl_Group(380, 0, 415, 200); + s->c_can->box(FL_DOWN_BOX); + s->c_can->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); + s->c_can->current(); - canvas_can = new Ca_Canvas(460, 35, 300, 100, "??? coefficients"); - canvas_can->box(FL_PLASTIC_DOWN_BOX); - canvas_can->color(7); - canvas_can->align(FL_ALIGN_TOP); - Fl_Group::current()->resizable(canvas_can); - canvas_can->border(15); + s->canvas_can = new Ca_Canvas(460, 35, 300, 100, "??? coefficients"); + s->canvas_can->box(FL_PLASTIC_DOWN_BOX); + s->canvas_can->color(7); + s->canvas_can->align(FL_ALIGN_TOP); + Fl_Group::current()->resizable(s->canvas_can); + s->canvas_can->border(15); - can_x = new Ca_X_Axis(465, 135, 290, 30, "Tap"); - can_x->align(FL_ALIGN_BOTTOM); - can_x->minimum(0.0); - can_x->maximum((float) len); - can_x->label_format("%g"); - can_x->minor_grid_color(fl_gray_ramp(20)); - can_x->major_grid_color(fl_gray_ramp(15)); - can_x->label_grid_color(fl_gray_ramp(10)); - can_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - can_x->minor_grid_style(FL_DOT); - can_x->major_step(5); - can_x->label_step(1); - can_x->axis_align(CA_BOTTOM | CA_LINE); - can_x->axis_color(FL_BLACK); - can_x->current(); + s->can_x = new Ca_X_Axis(465, 135, 290, 30, "Tap"); + s->can_x->align(FL_ALIGN_BOTTOM); + s->can_x->minimum(0.0); + s->can_x->maximum((float) len); + s->can_x->label_format("%g"); + s->can_x->minor_grid_color(fl_gray_ramp(20)); + s->can_x->major_grid_color(fl_gray_ramp(15)); + s->can_x->label_grid_color(fl_gray_ramp(10)); + s->can_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->can_x->minor_grid_style(FL_DOT); + s->can_x->major_step(5); + s->can_x->label_step(1); + s->can_x->axis_align(CA_BOTTOM | CA_LINE); + s->can_x->axis_color(FL_BLACK); + s->can_x->current(); - can_y = new Ca_Y_Axis(420, 40, 40, 90, "Amp"); - can_y->align(FL_ALIGN_LEFT); - can_y->minimum(-0.1); - can_y->maximum(0.1); - can_y->minor_grid_color(fl_gray_ramp(20)); - can_y->major_grid_color(fl_gray_ramp(15)); - can_y->label_grid_color(fl_gray_ramp(10)); - can_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - can_y->minor_grid_style(FL_DOT); - can_y->major_step(5); - can_y->label_step(1); - can_y->axis_color(FL_BLACK); - can_y->current(); + s->can_y = new Ca_Y_Axis(420, 40, 40, 90, "Amp"); + s->can_y->align(FL_ALIGN_LEFT); + s->can_y->minimum(-0.1); + s->can_y->maximum(0.1); + s->can_y->minor_grid_color(fl_gray_ramp(20)); + s->can_y->major_grid_color(fl_gray_ramp(15)); + s->can_y->label_grid_color(fl_gray_ramp(10)); + s->can_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->can_y->minor_grid_style(FL_DOT); + s->can_y->major_step(5); + s->can_y->label_step(1); + s->can_y->axis_color(FL_BLACK); + s->can_y->current(); - c_can->end(); + s->c_can->end(); - c_line_model = new Fl_Group(380, 200, 415, 200); - c_line_model->box(FL_DOWN_BOX); - c_line_model->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); - c_line_model->current(); + s->can_re = NULL; - canvas_line_model = new Ca_Canvas(460, 235, 300, 100, "Line impulse response model"); - canvas_line_model->box(FL_PLASTIC_DOWN_BOX); - canvas_line_model->color(7); - canvas_line_model->align(FL_ALIGN_TOP); - Fl_Group::current()->resizable(canvas_line_model); - canvas_line_model->border(15); + s->c_line_model = new Fl_Group(380, 200, 415, 200); + s->c_line_model->box(FL_DOWN_BOX); + s->c_line_model->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); + s->c_line_model->current(); - line_model_x = new Ca_X_Axis(465, 335, 290, 30, "Tap"); - line_model_x->align(FL_ALIGN_BOTTOM); - line_model_x->minimum(0.0); - line_model_x->maximum((float) len); - line_model_x->label_format("%g"); - line_model_x->minor_grid_color(fl_gray_ramp(20)); - line_model_x->major_grid_color(fl_gray_ramp(15)); - line_model_x->label_grid_color(fl_gray_ramp(10)); - line_model_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - line_model_x->minor_grid_style(FL_DOT); - line_model_x->major_step(5); - line_model_x->label_step(1); - line_model_x->axis_align(CA_BOTTOM | CA_LINE); - line_model_x->axis_color(FL_BLACK); - line_model_x->current(); + s->canvas_line_model = new Ca_Canvas(460, 235, 300, 100, "Line impulse response model"); + s->canvas_line_model->box(FL_PLASTIC_DOWN_BOX); + s->canvas_line_model->color(7); + s->canvas_line_model->align(FL_ALIGN_TOP); + Fl_Group::current()->resizable(s->canvas_line_model); + s->canvas_line_model->border(15); - line_model_y = new Ca_Y_Axis(420, 240, 40, 90, "Amp"); - line_model_y->align(FL_ALIGN_LEFT); - line_model_y->minimum(-0.1); - line_model_y->maximum(0.1); - line_model_y->minor_grid_color(fl_gray_ramp(20)); - line_model_y->major_grid_color(fl_gray_ramp(15)); - line_model_y->label_grid_color(fl_gray_ramp(10)); - line_model_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - line_model_y->minor_grid_style(FL_DOT); - line_model_y->major_step(5); - line_model_y->label_step(1); - line_model_y->axis_color(FL_BLACK); - line_model_y->current(); + s->line_model_x = new Ca_X_Axis(465, 335, 290, 30, "Tap"); + s->line_model_x->align(FL_ALIGN_BOTTOM); + s->line_model_x->minimum(0.0); + s->line_model_x->maximum((float) len); + s->line_model_x->label_format("%g"); + s->line_model_x->minor_grid_color(fl_gray_ramp(20)); + s->line_model_x->major_grid_color(fl_gray_ramp(15)); + s->line_model_x->label_grid_color(fl_gray_ramp(10)); + s->line_model_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->line_model_x->minor_grid_style(FL_DOT); + s->line_model_x->major_step(5); + s->line_model_x->label_step(1); + s->line_model_x->axis_align(CA_BOTTOM | CA_LINE); + s->line_model_x->axis_color(FL_BLACK); + s->line_model_x->current(); - c_line_model->end(); + s->line_model_y = new Ca_Y_Axis(420, 240, 40, 90, "Amp"); + s->line_model_y->align(FL_ALIGN_LEFT); + s->line_model_y->minimum(-0.1); + s->line_model_y->maximum(0.1); + s->line_model_y->minor_grid_color(fl_gray_ramp(20)); + s->line_model_y->major_grid_color(fl_gray_ramp(15)); + s->line_model_y->label_grid_color(fl_gray_ramp(10)); + s->line_model_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->line_model_y->minor_grid_style(FL_DOT); + s->line_model_y->major_step(5); + s->line_model_y->label_step(1); + s->line_model_y->axis_color(FL_BLACK); + s->line_model_y->current(); + s->line_model_re = NULL; - audio_meter = new Fl_Audio_Meter(810, 40, 10, 250, ""); - audio_meter->box(FL_PLASTIC_UP_BOX); - audio_meter->type(FL_VERT_AUDIO_METER); + s->c_line_model->end(); - c_right->end(); + s->audio_meter = new Fl_Audio_Meter(810, 40, 10, 250, ""); + s->audio_meter->box(FL_PLASTIC_UP_BOX); + s->audio_meter->type(FL_VERT_AUDIO_METER); - Fl_Group::current()->resizable(c_right); - w->end(); - w->show(); + s->c_right->end(); + + Fl_Group::current()->resizable(s->c_right); + s->w->end(); + s->w->show(); #if defined(HAVE_FFTW3_H) - p = fftw_plan_dft_1d(1024, in, out, FFTW_BACKWARD, FFTW_ESTIMATE); + s->p = fftw_plan_dft_1d(1024, s->in, s->out, FFTW_BACKWARD, FFTW_ESTIMATE); for (i = 0; i < 1024; i++) { - in[i][0] = 0.0; - in[i][1] = 0.0; + s->in[i][0] = 0.0; + s->in[i][1] = 0.0; } #else - p = fftw_create_plan(1024, FFTW_BACKWARD, FFTW_ESTIMATE); + s->p = fftw_create_plan(1024, FFTW_BACKWARD, FFTW_ESTIMATE); for (i = 0; i < 1024; i++) { - in[i].re = 0.0; - in[i].im = 0.0; + s->in[i].re = 0.0; + s->in[i].im = 0.0; } #endif - in_ptr = 0; + s->in_ptr = 0; Fl::check(); return 0; diff --git a/libs/spandsp/tests/media_monitor.cpp b/libs/spandsp/tests/media_monitor.cpp index 31dcdf657d..f798862ef7 100644 --- a/libs/spandsp/tests/media_monitor.cpp +++ b/libs/spandsp/tests/media_monitor.cpp @@ -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: media_monitor.cpp,v 1.4 2008/05/27 15:08:21 steveu Exp $ + * $Id: media_monitor.cpp,v 1.5 2008/09/08 16:10:41 steveu Exp $ */ #ifdef HAVE_CONFIG_H @@ -50,34 +50,37 @@ #include "spandsp.h" #include "media_monitor.h" -Fl_Double_Window *w; +struct line_model_monitor_s +{ + Fl_Double_Window *w; -Fl_Group *c_right; -Fl_Group *c_sent; -Fl_Group *c_received; + Fl_Group *c_right; + Fl_Group *c_sent; + Fl_Group *c_received; -Ca_Canvas *canvas_sent; -Ca_X_Axis *sent_x; -Ca_Y_Axis *sent_y; -Ca_Line *sent_re = NULL; -double sent_re_plot[1000]; -double sent_re_plot_min; -double sent_re_plot_max; + Ca_Canvas *canvas_sent; + Ca_X_Axis *sent_x; + Ca_Y_Axis *sent_y; + Ca_Line *sent_re; + double sent_re_plot[1000]; + double sent_re_plot_min; + double sent_re_plot_max; -Ca_Canvas *canvas_received; -Ca_X_Axis *received_x; -Ca_Y_Axis *received_y; -Ca_Line *received_delays = NULL; -double received_delays_plot[4000]; -double received_delays_plot_max; -int min_diff; -int max_diff; + Ca_Canvas *canvas_received; + Ca_X_Axis *received_x; + Ca_Y_Axis *received_y; + Ca_Line *received_delays; + double received_delays_plot[4000]; + double received_delays_plot_max; + int min_diff; + int max_diff; -int highest_seq_no_seen = -1; + int highest_seq_no_seen; +}; static int skip = 0; - -int in_ptr; +static struct line_model_monitor_s media; +static struct line_model_monitor_s *s = &media; void media_monitor_rx(int seq_no, double departure_time, double arrival_time) { @@ -85,61 +88,61 @@ void media_monitor_rx(int seq_no, double departure_time, double arrival_time) int diff; int i; - if (received_delays) - delete received_delays; + if (s->received_delays) + delete s->received_delays; - canvas_received->current(canvas_received); + s->canvas_received->current(s->canvas_received); fdiff = (arrival_time - departure_time)*1000.0; diff = (int) fdiff; if (diff < 0) diff = 0; else if (diff > 1999) diff = 1999; - received_delays_plot[2*diff + 1]++; - if (received_delays_plot[2*diff + 1] > received_delays_plot_max) + s->received_delays_plot[2*diff + 1]++; + if (s->received_delays_plot[2*diff + 1] > s->received_delays_plot_max) { - received_delays_plot_max = received_delays_plot[2*diff + 1]; - received_y->maximum(received_delays_plot_max); + s->received_delays_plot_max = s->received_delays_plot[2*diff + 1]; + s->received_y->maximum(s->received_delays_plot_max); } - if (diff > max_diff) + if (diff > s->max_diff) { - max_diff = diff; - received_x->maximum((double) max_diff); + s->max_diff = diff; + s->received_x->maximum((double) s->max_diff); } - if (diff < min_diff) + if (diff < s->min_diff) { - min_diff = diff - 1; - received_x->minimum((double) min_diff); + s->min_diff = diff - 1; + s->received_x->minimum((double) s->min_diff); } - received_delays = new Ca_Line(2000, received_delays_plot, 0, 0, FL_BLUE, CA_NO_POINT); + s->received_delays = new Ca_Line(2000, s->received_delays_plot, 0, 0, FL_BLUE, CA_NO_POINT); - if (sent_re) - delete sent_re; + if (s->sent_re) + delete s->sent_re; - canvas_sent->current(canvas_sent); + s->canvas_sent->current(s->canvas_sent); - if (seq_no > highest_seq_no_seen + 1) + if (seq_no > s->highest_seq_no_seen + 1) { - for (i = highest_seq_no_seen + 1; i < seq_no; i++) - sent_re_plot[2*(i%500) + 1] = 0.0; + for (i = s->highest_seq_no_seen + 1; i < seq_no; i++) + s->sent_re_plot[2*(i%500) + 1] = 0.0; } - sent_re_plot[2*(seq_no%500) + 1] = fdiff; + s->sent_re_plot[2*(seq_no%500) + 1] = fdiff; - if (fdiff > sent_re_plot_max) + if (fdiff > s->sent_re_plot_max) { - sent_re_plot_max = fdiff; - sent_y->maximum(sent_re_plot_max); + s->sent_re_plot_max = fdiff; + s->sent_y->maximum(s->sent_re_plot_max); } - if (fdiff < sent_re_plot_min) + if (fdiff < s->sent_re_plot_min) { - sent_re_plot_min = fdiff - 1.0; - sent_y->minimum(sent_re_plot_min); + s->sent_re_plot_min = fdiff - 1.0; + s->sent_y->minimum(s->sent_re_plot_min); } - sent_re = new Ca_Line(500, sent_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); + s->sent_re = new Ca_Line(500, s->sent_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); - if (seq_no > highest_seq_no_seen) - highest_seq_no_seen = seq_no; + if (seq_no > s->highest_seq_no_seen) + s->highest_seq_no_seen = seq_no; if (++skip >= 100) { @@ -159,116 +162,118 @@ int start_media_monitor(void) len = 128; - w = new Fl_Double_Window(465, 400, "IP streaming media monitor"); + s->w = new Fl_Double_Window(465, 400, "IP streaming media monitor"); - c_right = new Fl_Group(0, 0, 465, 405); + s->c_right = new Fl_Group(0, 0, 465, 405); - c_sent = new Fl_Group(0, 0, 465, 200); - c_sent->box(FL_DOWN_BOX); - c_sent->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); - c_sent->current(); + s->c_sent = new Fl_Group(0, 0, 465, 200); + s->c_sent->box(FL_DOWN_BOX); + s->c_sent->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); + s->c_sent->current(); - canvas_sent = new Ca_Canvas(110, 35, 300, 100, "Packet delays"); - canvas_sent->box(FL_PLASTIC_DOWN_BOX); - canvas_sent->color(7); - canvas_sent->align(FL_ALIGN_TOP); - Fl_Group::current()->resizable(canvas_sent); - canvas_sent->border(15); + s->canvas_sent = new Ca_Canvas(110, 35, 300, 100, "Packet delays"); + s->canvas_sent->box(FL_PLASTIC_DOWN_BOX); + s->canvas_sent->color(7); + s->canvas_sent->align(FL_ALIGN_TOP); + Fl_Group::current()->resizable(s->canvas_sent); + s->canvas_sent->border(15); - sent_x = new Ca_X_Axis(115, 135, 290, 30, "Packet"); - sent_x->align(FL_ALIGN_BOTTOM); - sent_x->minimum(0.0); - sent_x->maximum(500.0); - sent_x->label_format("%g"); - sent_x->minor_grid_color(fl_gray_ramp(20)); - sent_x->major_grid_color(fl_gray_ramp(15)); - sent_x->label_grid_color(fl_gray_ramp(10)); - sent_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - sent_x->minor_grid_style(FL_DOT); - sent_x->major_step(5); - sent_x->label_step(1); - sent_x->axis_align(CA_BOTTOM | CA_LINE); - sent_x->axis_color(FL_BLACK); - sent_x->current(); + s->sent_x = new Ca_X_Axis(115, 135, 290, 30, "Packet"); + s->sent_x->align(FL_ALIGN_BOTTOM); + s->sent_x->minimum(0.0); + s->sent_x->maximum(500.0); + s->sent_x->label_format("%g"); + s->sent_x->minor_grid_color(fl_gray_ramp(20)); + s->sent_x->major_grid_color(fl_gray_ramp(15)); + s->sent_x->label_grid_color(fl_gray_ramp(10)); + s->sent_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->sent_x->minor_grid_style(FL_DOT); + s->sent_x->major_step(5); + s->sent_x->label_step(1); + s->sent_x->axis_align(CA_BOTTOM | CA_LINE); + s->sent_x->axis_color(FL_BLACK); + s->sent_x->current(); - sent_y = new Ca_Y_Axis(60, 40, 50, 90, "Delay\n(ms)"); - sent_y->align(FL_ALIGN_LEFT); - sent_y->minimum(0.0); - sent_y->maximum(2000.0); - sent_y->minor_grid_color(fl_gray_ramp(20)); - sent_y->major_grid_color(fl_gray_ramp(15)); - sent_y->label_grid_color(fl_gray_ramp(10)); - sent_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - sent_y->minor_grid_style(FL_DOT); - sent_y->major_step(5); - sent_y->label_step(1); - sent_y->axis_color(FL_BLACK); - sent_y->current(); + s->sent_y = new Ca_Y_Axis(60, 40, 50, 90, "Delay\n(ms)"); + s->sent_y->align(FL_ALIGN_LEFT); + s->sent_y->minimum(0.0); + s->sent_y->maximum(2000.0); + s->sent_y->minor_grid_color(fl_gray_ramp(20)); + s->sent_y->major_grid_color(fl_gray_ramp(15)); + s->sent_y->label_grid_color(fl_gray_ramp(10)); + s->sent_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->sent_y->minor_grid_style(FL_DOT); + s->sent_y->major_step(5); + s->sent_y->label_step(1); + s->sent_y->axis_color(FL_BLACK); + s->sent_y->current(); - c_sent->end(); + s->c_sent->end(); - c_received = new Fl_Group(0, 200, 465, 200); - c_received->box(FL_DOWN_BOX); - c_received->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); - c_received->current(); + s->c_received = new Fl_Group(0, 200, 465, 200); + s->c_received->box(FL_DOWN_BOX); + s->c_received->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE); + s->c_received->current(); - canvas_received = new Ca_Canvas(110, 235, 300, 100, "Delay spread"); - canvas_received->box(FL_PLASTIC_DOWN_BOX); - canvas_received->color(7); - canvas_received->align(FL_ALIGN_TOP); - Fl_Group::current()->resizable(canvas_received); - canvas_received->border(15); + s->canvas_received = new Ca_Canvas(110, 235, 300, 100, "Delay spread"); + s->canvas_received->box(FL_PLASTIC_DOWN_BOX); + s->canvas_received->color(7); + s->canvas_received->align(FL_ALIGN_TOP); + Fl_Group::current()->resizable(s->canvas_received); + s->canvas_received->border(15); - received_x = new Ca_X_Axis(115, 335, 290, 30, "Delay (ms)"); - received_x->align(FL_ALIGN_BOTTOM); - received_x->minimum(0.0); - received_x->maximum(2000.0); - received_x->label_format("%g"); - received_x->minor_grid_color(fl_gray_ramp(20)); - received_x->major_grid_color(fl_gray_ramp(15)); - received_x->label_grid_color(fl_gray_ramp(10)); - received_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - received_x->minor_grid_style(FL_DOT); - received_x->major_step(5); - received_x->label_step(1); - received_x->axis_align(CA_BOTTOM | CA_LINE); - received_x->axis_color(FL_BLACK); - received_x->current(); + s->received_x = new Ca_X_Axis(115, 335, 290, 30, "Delay (ms)"); + s->received_x->align(FL_ALIGN_BOTTOM); + s->received_x->minimum(0.0); + s->received_x->maximum(2000.0); + s->received_x->label_format("%g"); + s->received_x->minor_grid_color(fl_gray_ramp(20)); + s->received_x->major_grid_color(fl_gray_ramp(15)); + s->received_x->label_grid_color(fl_gray_ramp(10)); + s->received_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->received_x->minor_grid_style(FL_DOT); + s->received_x->major_step(5); + s->received_x->label_step(1); + s->received_x->axis_align(CA_BOTTOM | CA_LINE); + s->received_x->axis_color(FL_BLACK); + s->received_x->current(); - received_y = new Ca_Y_Axis(60, 240, 50, 90, "Freq"); - received_y->align(FL_ALIGN_LEFT); - received_y->minimum(0.0); - received_y->maximum(50.0); - received_y->minor_grid_color(fl_gray_ramp(20)); - received_y->major_grid_color(fl_gray_ramp(15)); - received_y->label_grid_color(fl_gray_ramp(10)); - received_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); - received_y->minor_grid_style(FL_DOT); - received_y->major_step(5); - received_y->label_step(1); - received_y->axis_color(FL_BLACK); - received_y->current(); + s->received_y = new Ca_Y_Axis(60, 240, 50, 90, "Freq"); + s->received_y->align(FL_ALIGN_LEFT); + s->received_y->minimum(0.0); + s->received_y->maximum(50.0); + s->received_y->minor_grid_color(fl_gray_ramp(20)); + s->received_y->major_grid_color(fl_gray_ramp(15)); + s->received_y->label_grid_color(fl_gray_ramp(10)); + s->received_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE); + s->received_y->minor_grid_style(FL_DOT); + s->received_y->major_step(5); + s->received_y->label_step(1); + s->received_y->axis_color(FL_BLACK); + s->received_y->current(); for (i = 0; i < 2000; i++) - received_delays_plot[2*i] = i; - received_delays_plot_max = 0.0; - min_diff = 2000; - max_diff = 0; + s->received_delays_plot[2*i] = i; + s->received_delays_plot_max = 0.0; + s->min_diff = 2000; + s->max_diff = 0; + s->received_delays = NULL; + s->highest_seq_no_seen = -1; + for (i = 0; i < 500; i++) - sent_re_plot[2*i] = i; - sent_re_plot_min = 99999.0; - sent_re_plot_max = 0.0; + s->sent_re_plot[2*i] = i; + s->sent_re_plot_min = 99999.0; + s->sent_re_plot_max = 0.0; + s->sent_re = NULL; - c_received->end(); + s->c_received->end(); - c_right->end(); + s->c_right->end(); - Fl_Group::current()->resizable(c_right); - w->end(); - w->show(); - - in_ptr = 0; + Fl_Group::current()->resizable(s->c_right); + s->w->end(); + s->w->show(); Fl::check(); return 0; diff --git a/libs/spandsp/tests/modem_monitor.cpp b/libs/spandsp/tests/modem_monitor.cpp index 3cd0563edd..7086013d15 100644 --- a/libs/spandsp/tests/modem_monitor.cpp +++ b/libs/spandsp/tests/modem_monitor.cpp @@ -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: modem_monitor.cpp,v 1.15 2008/05/27 15:08:21 steveu Exp $ + * $Id: modem_monitor.cpp,v 1.17 2008/09/04 14:40:05 steveu Exp $ */ #ifdef HAVE_CONFIG_H @@ -54,6 +54,8 @@ #define SYMBOL_TRACKER_POINTS 12000 #define CARRIER_TRACKER_POINTS 12000 +#define FP_FACTOR 4096 + struct qam_monitor_s { Fl_Double_Window *w; @@ -165,9 +167,9 @@ int qam_monitor_update_equalizer(qam_monitor_t *s, const complexf_t *coeffs, int break; if (isnan(coeffs[i].im) || isinf(coeffs[i].im)) break; - if (coeffs[i].re < -20.0 || coeffs[i].re > 20.0) + if (coeffs[i].re < -20.0f || coeffs[i].re > 20.0f) break; - if (coeffs[i].im < -20.0 || coeffs[i].im > 20.0) + if (coeffs[i].im < -20.0f || coeffs[i].im > 20.0f) break; } if (i != len) @@ -214,6 +216,55 @@ int qam_monitor_update_equalizer(qam_monitor_t *s, const complexf_t *coeffs, int } /*- End of function --------------------------------------------------------*/ +int qam_monitor_update_int_equalizer(qam_monitor_t *s, const complexi16_t *coeffs, int len) +{ + int i; + float min; + float max; + + if (s->eq_re) + delete s->eq_re; + if (s->eq_im) + delete s->eq_im; + + s->canvas_eq->current(s->canvas_eq); + i = 0; + min = coeffs[i].re; + if (min > coeffs[i].im) + min = coeffs[i].im; + max = coeffs[i].re; + if (max < coeffs[i].im) + max = coeffs[i].im; + for (i = 0; i < len; i++) + { + s->eq_re_plot[2*i] = (i - len/2)/2.0f; + s->eq_re_plot[2*i + 1] = coeffs[i].re/(float) FP_FACTOR; + if (min > coeffs[i].re) + min = coeffs[i].re; + if (max < coeffs[i].re) + max = coeffs[i].re; + + s->eq_im_plot[2*i] = (i - len/2)/2.0f; + s->eq_im_plot[2*i + 1] = coeffs[i].im/(float) FP_FACTOR; + if (min > coeffs[i].im) + min = coeffs[i].im; + if (max < coeffs[i].im) + max = coeffs[i].im; + } + min /= (float) FP_FACTOR; + max /= (float) FP_FACTOR; + + s->eq_x->minimum(-len/4.0); + s->eq_x->maximum(len/4.0); + s->eq_y->maximum((max == min) ? max + 0.2 : max); + s->eq_y->minimum(min); + s->eq_re = new Ca_Line(len, s->eq_re_plot, 0, 0, FL_BLUE, CA_NO_POINT); + s->eq_im = new Ca_Line(len, s->eq_im_plot, 0, 0, FL_RED, CA_NO_POINT); + Fl::check(); + return 0; +} +/*- End of function --------------------------------------------------------*/ + int qam_monitor_update_symbol_tracking(qam_monitor_t *s, float total_correction) { int i; diff --git a/libs/spandsp/tests/modem_monitor.h b/libs/spandsp/tests/modem_monitor.h index 66546ae7c6..636ef3f1c5 100644 --- a/libs/spandsp/tests/modem_monitor.h +++ b/libs/spandsp/tests/modem_monitor.h @@ -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: modem_monitor.h,v 1.15 2008/04/26 13:39:17 steveu Exp $ + * $Id: modem_monitor.h,v 1.16 2008/09/03 13:41:42 steveu Exp $ */ /*! \page constel_page Modem performance monitoring @@ -56,6 +56,7 @@ qam_monitor_t *qam_monitor_init(float constel_width, const char *tag); int qam_monitor_clear_constel(qam_monitor_t *s); int qam_monitor_update_constel(qam_monitor_t *s, const complexf_t *pt); int qam_monitor_update_equalizer(qam_monitor_t *s, const complexf_t *coeffs, int len); +int qam_monitor_update_int_equalizer(qam_monitor_t *s, const complexi16_t *coeffs, int len); int qam_monitor_update_symbol_tracking(qam_monitor_t *s, float total_correction); int qam_monitor_update_carrier_tracking(qam_monitor_t *s, float carrier); int qam_monitor_update_audio_level(qam_monitor_t *s, const int16_t amp[], int len); diff --git a/libs/spandsp/tests/oki_adpcm_tests.c b/libs/spandsp/tests/oki_adpcm_tests.c index bb6cf41dc5..fa3b39e2ce 100644 --- a/libs/spandsp/tests/oki_adpcm_tests.c +++ b/libs/spandsp/tests/oki_adpcm_tests.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: oki_adpcm_tests.c,v 1.34 2008/08/29 09:28:13 steveu Exp $ + * $Id: oki_adpcm_tests.c,v 1.35 2008/09/04 14:40:05 steveu Exp $ */ /*! \file */ @@ -70,7 +70,6 @@ int main(int argc, char *argv[]) int outframes; int oki_bytes; int bit_rate; - float x; double pre_energy; double post_energy; double diff_energy; diff --git a/libs/spandsp/tests/regression_tests.sh b/libs/spandsp/tests/regression_tests.sh index b59de74ddb..20848d6b00 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.51 2008/05/03 07:37:06 steveu Exp $ +# $Id: regression_tests.sh,v 1.52 2008/09/02 13:56:10 steveu Exp $ # ITUTESTS_TIF=../test-data/itu/fax/itutests.tif @@ -517,6 +517,15 @@ then fi echo t38_gateway_to_terminal_tests completed OK +./t38_non_ecm_buffer_tests >$STDOUT_DEST 2>$STDERR_DEST +RETVAL=$? +if [ $RETVAL != 0 ] +then + echo t38_non_ecm_buffer_tests failed! + exit $RETVAL +fi +echo t38_non_ecm_buffer_tests completed OK + rm -f t38.tif ./t38_terminal_to_gateway_tests >$STDOUT_DEST 2>$STDERR_DEST RETVAL=$? diff --git a/libs/spandsp/tests/super_tone_rx_tests.c b/libs/spandsp/tests/super_tone_rx_tests.c index 7a34b599cf..aa6be75964 100644 --- a/libs/spandsp/tests/super_tone_rx_tests.c +++ b/libs/spandsp/tests/super_tone_rx_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: super_tone_rx_tests.c,v 1.28 2008/05/13 13:17:26 steveu Exp $ + * $Id: super_tone_rx_tests.c,v 1.29 2008/08/30 16:47:35 steveu Exp $ */ /*! \file */ @@ -264,7 +264,7 @@ static void get_tone_set(super_tone_rx_descriptor_t *desc, const char *tone_file xmlDocPtr doc; xmlNsPtr ns; xmlNodePtr cur; -#if 0 +#if 1 xmlValidCtxt valid; #endif xmlChar *x; @@ -272,15 +272,14 @@ static void get_tone_set(super_tone_rx_descriptor_t *desc, const char *tone_file ns = NULL; xmlKeepBlanksDefault(0); xmlCleanupParser(); - doc = xmlParseFile(tone_file); - if (doc == NULL) + if ((doc = xmlParseFile(tone_file)) == NULL) { fprintf(stderr, "No document\n"); exit(2); } /*endif*/ xmlXIncludeProcess(doc); -#if 0 +#if 1 if (!xmlValidateDocument(&valid, doc)) { fprintf(stderr, "Invalid document\n"); diff --git a/libs/spandsp/tests/t38_non_ecm_buffer_tests.c b/libs/spandsp/tests/t38_non_ecm_buffer_tests.c index e3700fc712..21a4ad80c4 100644 --- a/libs/spandsp/tests/t38_non_ecm_buffer_tests.c +++ b/libs/spandsp/tests/t38_non_ecm_buffer_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: t38_non_ecm_buffer_tests.c,v 1.1 2008/08/14 14:06:06 steveu Exp $ + * $Id: t38_non_ecm_buffer_tests.c,v 1.2 2008/09/02 13:56:10 steveu Exp $ */ /*! \file */ @@ -64,7 +64,10 @@ int main(int argc, char *argv[]) uint8_t buf[1024]; int bit; int n; + int log_bits; + int i; + log_bits = FALSE; span_log_init(&logging, SPAN_LOG_FLOW, NULL); span_log_set_protocol(&logging, "Buffer"); @@ -79,10 +82,12 @@ int main(int argc, char *argv[]) do { bit = t38_non_ecm_buffer_get_bit((void *) &buffer); - printf("Rx bit %d - %d\n", n++, bit); + if (log_bits) + printf("Rx bit %d - %d\n", n++, bit); } while (bit >= 0); - t38_non_ecm_buffer_report_status(&buffer, &logging); + t38_non_ecm_buffer_report_input_status(&buffer, &logging); + t38_non_ecm_buffer_report_output_status(&buffer, &logging); t38_non_ecm_buffer_init(&buffer, TRUE, 0); memset(buf, 0, sizeof(buf)); @@ -95,10 +100,12 @@ int main(int argc, char *argv[]) do { bit = t38_non_ecm_buffer_get_bit((void *) &buffer); - printf("Rx bit %d - %d\n", n++, bit); + if (log_bits) + printf("Rx bit %d - %d\n", n++, bit); } while (bit >= 0); - t38_non_ecm_buffer_report_status(&buffer, &logging); + t38_non_ecm_buffer_report_input_status(&buffer, &logging); + t38_non_ecm_buffer_report_output_status(&buffer, &logging); t38_non_ecm_buffer_init(&buffer, TRUE, 400); memset(buf, 0, sizeof(buf)); @@ -111,10 +118,73 @@ int main(int argc, char *argv[]) do { bit = t38_non_ecm_buffer_get_bit((void *) &buffer); - printf("Rx bit %d - %d\n", n++, bit); + if (log_bits) + printf("Rx bit %d - %d\n", n++, bit); } while (bit >= 0); - t38_non_ecm_buffer_report_status(&buffer, &logging); + t38_non_ecm_buffer_report_input_status(&buffer, &logging); + t38_non_ecm_buffer_report_output_status(&buffer, &logging); + + t38_non_ecm_buffer_init(&buffer, TRUE, 400); + /* Get some initial bits from an empty buffer. These should be ones */ + for (i = 0; i < 1000; i++) + { + bit = t38_non_ecm_buffer_get_bit((void *) &buffer); + if (log_bits) + printf("Rx bit %d - %d\n", n++, bit); + if (bit != 1) + { + printf("Tests failed\n"); + exit(2); + } + } + /* Now put some zeros into the buffer, but no EOL. We should continue + getting ones out. */ + memset(buf, 0, sizeof(buf)); + t38_non_ecm_buffer_inject(&buffer, buf, 20); + for (i = 0; i < 1000; i++) + { + bit = t38_non_ecm_buffer_get_bit((void *) &buffer); + if (log_bits) + printf("Rx bit %d - %d\n", n++, bit); + if (bit != 1) + { + printf("Tests failed\n"); + exit(2); + } + } + /* Now add a one, to make an EOL. We should see the zeros come out. */ + buf[0] = 0x01; + t38_non_ecm_buffer_inject(&buffer, buf, 1); + for (i = 0; i < 1000; i++) + { + bit = t38_non_ecm_buffer_get_bit((void *) &buffer); + if (log_bits) + printf("Rx bit %d - %d\n", n++, bit); + if (bit != 0) + { + printf("Tests failed\n"); + exit(2); + } + } + /* Now add another line. We should see the first line come out. This means just the + eighth bit from now will be a one. */ + buf[0] = 0x00; + buf[4] = 0x01; + t38_non_ecm_buffer_inject(&buffer, buf, 5); + for (i = 0; i < 1000; i++) + { + bit = t38_non_ecm_buffer_get_bit((void *) &buffer); + if (log_bits) + printf("Rx bit %d - %d\n", n++, bit); + if (i != 7 && bit != 0) + { + printf("Tests failed (%d)\n", i); + exit(2); + } + } + t38_non_ecm_buffer_report_input_status(&buffer, &logging); + t38_non_ecm_buffer_report_output_status(&buffer, &logging); printf("Tests passed\n"); return 0; diff --git a/libs/spandsp/tests/t4_tests.c b/libs/spandsp/tests/t4_tests.c index c3f62517ca..6e61208aa8 100644 --- a/libs/spandsp/tests/t4_tests.c +++ b/libs/spandsp/tests/t4_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: t4_tests.c,v 1.58 2008/08/17 16:25:52 steveu Exp $ + * $Id: t4_tests.c,v 1.60 2008/09/07 12:45:17 steveu Exp $ */ /*! \file */ @@ -297,23 +297,23 @@ int main(int argc, char *argv[]) t4_rx_start_page(&receive_state); while (fgets(buf, 1024, stdin)) { - if (sscanf(buf, "HDLC: FCD: 06 %x", &bit) == 1) + if (sscanf(buf, "HDLC: FCD: 06 %x", (unsigned int *) &bit) == 1) { /* Useful for breaking up T.38 ECM logs */ for (i = 0; i < 256; i++) { - if (sscanf(&buf[18 + 3*i], "%x", &bit) != 1) + if (sscanf(&buf[18 + 3*i], "%x", (unsigned int *) &bit) != 1) break; if ((end_of_page = t4_rx_put_byte(&receive_state, bit))) break; } } - else if (strlen(buf) > 62 && sscanf(buf + 62, "Rx %d: IFP %x %x", &bit, &bit, &bit) == 3) + else if (strlen(buf) > 62 && sscanf(buf + 62, "Rx %*d: IFP %*x %*x") == 3) { /* Useful for breaking up T.38 non-ECM logs */ for (i = 0; i < 256; i++) { - if (sscanf(&buf[62 + 29 + 3*i], "%x", &bit) != 1) + if (sscanf(&buf[62 + 29 + 3*i], "%x", (unsigned int *) &bit) != 1) break; bit = bit_reverse8(bit); if ((end_of_page = t4_rx_put_byte(&receive_state, bit))) @@ -405,7 +405,7 @@ int main(int argc, char *argv[]) do { bit = t4_tx_get_bit(&send_state); - if (bit == PUTBIT_END_OF_DATA) + if (bit == SIG_STATUS_END_OF_DATA) { /* T.6 data does not contain an image termination sequence. T.4 1D and 2D do, and should locate that sequence. */ @@ -547,7 +547,7 @@ int main(int argc, char *argv[]) do { bit = t4_tx_get_bit(&send_state); - if (bit == PUTBIT_END_OF_DATA) + if (bit == SIG_STATUS_END_OF_DATA) { /* T.6 data does not contain an image termination sequence. T.4 1D and 2D do, and should locate that sequence. */ diff --git a/libs/spandsp/tests/tsb85_tests.c b/libs/spandsp/tests/tsb85_tests.c index 09517b5ea2..dc45572818 100644 --- a/libs/spandsp/tests/tsb85_tests.c +++ b/libs/spandsp/tests/tsb85_tests.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: tsb85_tests.c,v 1.19 2008/08/13 00:11:30 steveu Exp $ + * $Id: tsb85_tests.c,v 1.22 2008/09/09 15:30:43 steveu Exp $ */ /*! \file */ @@ -60,6 +60,7 @@ #endif #include "spandsp.h" +#include "spandsp-sim.h" #include "fax_tester.h" #define OUTPUT_TIFF_FILE_NAME "tsb85.tif" @@ -69,7 +70,6 @@ #define SAMPLES_PER_CHUNK 160 AFfilehandle out_handle; -AFfilesetup filesetup; int use_receiver_not_ready = FALSE; int test_local_interrupt = FALSE; @@ -84,28 +84,122 @@ uint8_t image[1000000]; uint8_t awaited[1000]; int awaited_len = 0; +t30_exchanged_info_t expected_rx_info; + static int next_step(faxtester_state_t *s); static int phase_b_handler(t30_state_t *s, void *user_data, int result) { int i; + int status; const char *u; i = (intptr_t) user_data; + status = T30_ERR_OK; if ((u = t30_get_rx_ident(s))) + { printf("%d: Phase B: remote ident '%s'\n", i, u); + if (expected_rx_info.ident[0] && strcmp(expected_rx_info.ident, u)) + { + printf("%d: Phase B: remote ident incorrect! - expected '%s'\n", i, expected_rx_info.ident); + status = T30_ERR_IDENT_UNACCEPTABLE; + } + } + else + { + if (expected_rx_info.ident[0]) + { + printf("%d: Phase B: remote ident missing!\n", i); + status = T30_ERR_IDENT_UNACCEPTABLE; + } + } if ((u = t30_get_rx_sub_address(s))) + { printf("%d: Phase B: remote sub-address '%s'\n", i, u); + if (expected_rx_info.sub_address[0] && strcmp(expected_rx_info.sub_address, u)) + { + printf("%d: Phase B: remote sub-address incorrect! - expected '%s'\n", i, expected_rx_info.sub_address); + status = T30_ERR_SUB_UNACCEPTABLE; + } + } + else + { + if (expected_rx_info.sub_address[0]) + { + printf("%d: Phase B: remote sub-address missing!\n", i); + status = T30_ERR_SUB_UNACCEPTABLE; + } + } if ((u = t30_get_rx_polled_sub_address(s))) + { printf("%d: Phase B: remote polled sub-address '%s'\n", i, u); + if (expected_rx_info.polled_sub_address[0] && strcmp(expected_rx_info.polled_sub_address, u)) + { + printf("%d: Phase B: remote polled sub-address incorrect! - expected '%s'\n", i, expected_rx_info.polled_sub_address); + status = T30_ERR_PSA_UNACCEPTABLE; + } + } + else + { + if (expected_rx_info.polled_sub_address[0]) + { + printf("%d: Phase B: remote polled sub-address missing!\n", i); + status = T30_ERR_PSA_UNACCEPTABLE; + } + } if ((u = t30_get_rx_selective_polling_address(s))) + { printf("%d: Phase B: remote selective polling address '%s'\n", i, u); + if (expected_rx_info.selective_polling_address[0] && strcmp(expected_rx_info.selective_polling_address, u)) + { + printf("%d: Phase B: remote selective polling address incorrect! - expected '%s'\n", i, expected_rx_info.selective_polling_address); + status = T30_ERR_SEP_UNACCEPTABLE; + } + } + else + { + if (expected_rx_info.selective_polling_address[0]) + { + printf("%d: Phase B: remote selective polling address missing!\n", i); + status = T30_ERR_SEP_UNACCEPTABLE; + } + } if ((u = t30_get_rx_sender_ident(s))) + { printf("%d: Phase B: remote sender ident '%s'\n", i, u); + if (expected_rx_info.sender_ident[0] && strcmp(expected_rx_info.sender_ident, u)) + { + printf("%d: Phase B: remote sender ident incorrect! - expected '%s'\n", i, expected_rx_info.sender_ident); + status = T30_ERR_SID_UNACCEPTABLE; + } + } + else + { + if (expected_rx_info.sender_ident[0]) + { + printf("%d: Phase B: remote sender ident missing!\n", i); + status = T30_ERR_SID_UNACCEPTABLE; + } + } if ((u = t30_get_rx_password(s))) + { printf("%d: Phase B: remote password '%s'\n", i, u); + if (expected_rx_info.password[0] && strcmp(expected_rx_info.password, u)) + { + printf("%d: Phase B: remote password incorrect! - expected '%s'\n", i, expected_rx_info.password); + status = T30_ERR_PWD_UNACCEPTABLE; + } + } + else + { + if (expected_rx_info.password[0]) + { + printf("%d: Phase B: remote password missing!\n", i); + status = T30_ERR_PWD_UNACCEPTABLE; + } + } printf("%d: Phase B handler on channel %d - (0x%X) %s\n", i, i, result, t30_frametype(result)); - return T30_ERR_OK; + return status; } /*- End of function --------------------------------------------------------*/ @@ -184,7 +278,8 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) printf("%d: Phase E: longest bad row run %d\n", i, t.longest_bad_row_run); printf("%d: Phase E: coding method %s\n", i, t4_encoding_to_str(t.encoding)); printf("%d: Phase E: image size %d bytes\n", i, t.image_size); - //printf("%d: Phase E: local ident '%s'\n", i, info->ident); + if ((u = t30_get_tx_ident(s))) + printf("%d: Phase E: local ident '%s'\n", i, u); if ((u = t30_get_rx_ident(s))) printf("%d: Phase E: remote ident '%s'\n", i, u); if ((u = t30_get_rx_country(s))) @@ -207,10 +302,11 @@ static void t30_real_time_frame_handler(t30_state_t *s, } else { - printf("T.30: Real time frame handler - %s, %s, length = %d\n", - (direction) ? "line->T.30" : "T.30->line", - t30_frametype(msg[2]), - len); + fprintf(stderr, + "T.30: Real time frame handler - %s, %s, length = %d\n", + (direction) ? "line->T.30" : "T.30->line", + t30_frametype(msg[2]), + len); } } /*- End of function --------------------------------------------------------*/ @@ -220,7 +316,7 @@ static int document_handler(t30_state_t *s, void *user_data, int event) int i; i = (intptr_t) user_data; - printf("%d: Document handler on channel %d - event %d\n", i, i, event); + fprintf(stderr, "%d: Document handler on channel %d - event %d\n", i, i, event); return FALSE; } /*- End of function --------------------------------------------------------*/ @@ -237,11 +333,12 @@ static void faxtester_real_time_frame_handler(faxtester_state_t *s, } else { - printf("Real time frame handler - %s, %s, length = %d\n", - (direction) ? "line->tester" : "tester->line", - t30_frametype(msg[2]), - len); - if (direction && msg[1] == 0x13) + fprintf(stderr, + "TST: Real time frame handler - %s, %s, length = %d\n", + (direction) ? "line->tester" : "tester->line", + t30_frametype(msg[2]), + len); + if (direction && msg[1] == awaited[1]) { if ((awaited_len >= 0 && len != abs(awaited_len)) || @@ -249,12 +346,12 @@ static void faxtester_real_time_frame_handler(faxtester_state_t *s, || memcmp(msg, awaited, abs(awaited_len)) != 0) { - span_log_buf(&s->logging, SPAN_LOG_FLOW, "Expected", awaited, awaited_len); + span_log_buf(&s->logging, SPAN_LOG_FLOW, "Expected", awaited, abs(awaited_len)); span_log_buf(&s->logging, SPAN_LOG_FLOW, "Received", msg, len); exit(2); } } - if (msg[1] == 0x13) + if (msg[1] == awaited[1]) next_step(s); } } @@ -280,13 +377,17 @@ static void fax_prepare(void) t30 = fax_get_t30_state(&fax); fax_set_transmit_on_idle(&fax, TRUE); fax_set_tep_mode(&fax, TRUE); +#if 0 t30_set_tx_ident(t30, "1234567890"); t30_set_tx_sub_address(t30, "Sub-address"); t30_set_tx_sender_ident(t30, "Sender ID"); t30_set_tx_password(t30, "Password"); t30_set_tx_polled_sub_address(t30, "Polled sub-address"); t30_set_tx_selective_polling_address(t30, "Sel polling address"); - t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12); +#endif + t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSF\x00", 16); + //t30_set_tx_nss(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSS\x00", 16); + t30_set_tx_nsc(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSC\x00", 16); t30_set_ecm_capability(t30, TRUE); t30_set_supported_t30_features(t30, T30_SUPPORT_IDENTIFICATION @@ -531,6 +632,7 @@ static int next_step(faxtester_state_t *s) { /* Add a bit of waiting at the end, to ensure everything gets flushed through, any timers can expire, etc. */ + faxtester_set_timeout(s, -1); faxtester_set_rx_type(s, T30_MODEM_NONE, 0, FALSE, FALSE); faxtester_set_tx_type(s, T30_MODEM_PAUSE, 0, 120000, FALSE); s->final_delayed = TRUE; @@ -628,7 +730,24 @@ static int next_step(faxtester_state_t *s) span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised modem\n"); } } - if (strcasecmp((const char *) type, "CNG") == 0) + + if (strcasecmp((const char *) type, "SET") == 0) + { + if (strcasecmp((const char *) tag, "IDENT") == 0) + strcpy(expected_rx_info.ident, (const char *) value); + else if (strcasecmp((const char *) tag, "SUB") == 0) + strcpy(expected_rx_info.sub_address, (const char *) value); + else if (strcasecmp((const char *) tag, "SEP") == 0) + strcpy(expected_rx_info.selective_polling_address, (const char *) value); + else if (strcasecmp((const char *) tag, "PSA") == 0) + strcpy(expected_rx_info.polled_sub_address, (const char *) value); + else if (strcasecmp((const char *) tag, "SID") == 0) + strcpy(expected_rx_info.sender_ident, (const char *) value); + else if (strcasecmp((const char *) tag, "PWD") == 0) + strcpy(expected_rx_info.password, (const char *) value); + return 0; + } + else if (strcasecmp((const char *) type, "CNG") == 0) { /* Look for CNG */ faxtester_set_rx_type(s, T30_MODEM_CNG, 0, FALSE, FALSE); @@ -715,7 +834,33 @@ static int next_step(faxtester_state_t *s) } } - if (strcasecmp((const char *) type, "CALL") == 0) + if (strcasecmp((const char *) type, "SET") == 0) + { + t30 = fax_get_t30_state(&fax); + if (strcasecmp((const char *) tag, "IDENT") == 0) + t30_set_tx_ident(t30, (const char *) value); + else if (strcasecmp((const char *) tag, "SUB") == 0) + t30_set_tx_sub_address(t30, (const char *) value); + else if (strcasecmp((const char *) tag, "SEP") == 0) + t30_set_tx_selective_polling_address(t30, (const char *) value); + else if (strcasecmp((const char *) tag, "PSA") == 0) + t30_set_tx_polled_sub_address(t30, (const char *) value); + else if (strcasecmp((const char *) tag, "SID") == 0) + t30_set_tx_sender_ident(t30, (const char *) value); + else if (strcasecmp((const char *) tag, "PWD") == 0) + t30_set_tx_password(t30, (const char *) value); + else if (strcasecmp((const char *) tag, "RXFILE") == 0) + { + if (value) + t30_set_rx_file(t30, (const char *) value, -1); + else + t30_set_rx_file(t30, output_tiff_file_name, -1); + } + else if (strcasecmp((const char *) tag, "TXFILE") == 0) + t30_set_tx_file(t30, (const char *) value, -1, -1); + return 0; + } + else if (strcasecmp((const char *) type, "CALL") == 0) { fax_init(&fax, FALSE); fax_prepare(); @@ -898,18 +1043,7 @@ static void exchange(faxtester_state_t *s) if (log_audio) { - if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP) - { - fprintf(stderr, " Failed to create file setup\n"); - exit(2); - } - /*endif*/ - afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); - afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); - afInitFileFormat(filesetup, AF_FILE_WAVE); - afInitChannels(filesetup, AF_DEFAULT_TRACK, 2); - - if ((out_handle = afOpenFile(OUTPUT_FILE_NAME_WAVE, "w", filesetup)) == AF_NULL_FILEHANDLE) + if ((out_handle = afOpenFile_telephony_write(OUTPUT_FILE_NAME_WAVE, 2)) == AF_NULL_FILEHANDLE) { fprintf(stderr, " Cannot create wave file '%s'\n", OUTPUT_FILE_NAME_WAVE); exit(2); @@ -975,7 +1109,6 @@ static void exchange(faxtester_state_t *s) exit(2); } /*endif*/ - afFreeFileSetup(filesetup); } /*endif*/ } @@ -1014,22 +1147,21 @@ static int get_test_set(faxtester_state_t *s, const char *test_file, const char xmlDocPtr doc; xmlNsPtr ns; xmlNodePtr cur; -#if 0 +#if 1 xmlValidCtxt valid; #endif ns = NULL; xmlKeepBlanksDefault(0); xmlCleanupParser(); - doc = xmlParseFile(test_file); - if (doc == NULL) + if ((doc = xmlParseFile(test_file)) == NULL) { span_log(&s->logging, SPAN_LOG_FLOW, "No document\n"); exit(2); } /*endif*/ xmlXIncludeProcess(doc); -#if 0 +#if 1 if (!xmlValidateDocument(&valid, doc)) { span_log(&s->logging, SPAN_LOG_FLOW, "Invalid document\n"); @@ -1091,6 +1223,7 @@ int main(int argc, char *argv[]) test_name = argv[1]; faxtester_init(&state, TRUE); + memset(&expected_rx_info, 0, sizeof(expected_rx_info)); span_log_set_level(&state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); span_log_set_tag(&state.logging, "B"); get_test_set(&state, "../spandsp/tsb85.xml", test_name); diff --git a/libs/spandsp/tests/tsb85_tests.sh b/libs/spandsp/tests/tsb85_tests.sh index 0e2c1c7b19..52fd4f9eb1 100755 --- a/libs/spandsp/tests/tsb85_tests.sh +++ b/libs/spandsp/tests/tsb85_tests.sh @@ -15,7 +15,7 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # -# $Id: tsb85_tests.sh,v 1.3 2008/08/04 14:03:17 steveu Exp $ +# $Id: tsb85_tests.sh,v 1.4 2008/09/09 15:30:43 steveu Exp $ # run_tsb85_test() @@ -36,7 +36,7 @@ for TEST in MRGN01 MRGN02 MRGN03 MRGN04 MRGN05 MRGN06a MRGN06b MRGN07 MRGN08 ; d done #for TEST in MRGN09 MRGN10 MRGN11 MRGN12 MRGN13 MRGN14 MRGN15 MRGN16 MRGN17 ; do -for TEST in MRGN09 MRGN10 MRGN11 MRGN12 MRGN13 MRGN15 MRGN17 ; do +for TEST in MRGN09 MRGN10 MRGN11 MRGN12 MRGN13 MRGN15 ; do run_tsb85_test done @@ -54,7 +54,7 @@ for TEST in MRGX02 MRGX04 MRGX06 MRGX07 MRGX08 ; do done #for TEST in MRGX09 MRGX10 MRGX11 MRGX12 MRGX13 MRGX14 MRGX15 ; do -for TEST in MRGX09 MRGX10 MRGX11 ; do +for TEST in MRGX09 MRGX11 ; do run_tsb85_test done @@ -91,14 +91,14 @@ done #done #for TEST in MTGX17 MTGX18 MTGX19 MTGX20 MTGX21 MTGX22 MTGX23 ; do -# run_tsb85_test -#done - -#for TEST in MRGP01 MRGP02 MRGP03 MRGP04 MRGP05 MRGP06 MRGP07 MRGP08 ; do -for TEST in MRGP03 MRGP04 MRGP05 ; do +for TEST in MTGX18 MTGX19 MTGX20 MTGX21 MTGX22 MTGX23 ; do run_tsb85_test done -#for TEST in ORGP09 ORGP10 ; do -# run_tsb85_test -#done +for TEST in MRGP01 MRGP02 MRGP03 MRGP04 MRGP05 MRGP06 MRGP07 MRGP08 ; do + run_tsb85_test +done + +for TEST in ORGP09 ORGP10 ; do + run_tsb85_test +done diff --git a/libs/spandsp/tests/v17_tests.c b/libs/spandsp/tests/v17_tests.c index 97a63db348..a0c2c73773 100644 --- a/libs/spandsp/tests/v17_tests.c +++ b/libs/spandsp/tests/v17_tests.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: v17_tests.c,v 1.87 2008/08/29 09:28:13 steveu Exp $ + * $Id: v17_tests.c,v 1.90 2008/09/07 12:45:17 steveu Exp $ */ /*! \page v17_tests_page V.17 modem tests @@ -141,32 +141,16 @@ static int v17_rx_status(void *user_data, int status) int len; complexf_t *coeffs; - printf("V.17 rx status is %d\n", status); + printf("V.17 rx status is %s (%d)\n", signal_status_to_str(status), status); rx = (v17_rx_state_t *) user_data; switch (status) { - case PUTBIT_TRAINING_FAILED: - printf("Training failed\n"); - break; - case PUTBIT_TRAINING_IN_PROGRESS: - printf("Training in progress\n"); - break; - case PUTBIT_TRAINING_SUCCEEDED: - printf("Training succeeded\n"); + case SIG_STATUS_TRAINING_SUCCEEDED: len = v17_rx_equalizer_state(rx, &coeffs); printf("Equalizer:\n"); for (i = 0; i < len; i++) printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); break; - case PUTBIT_CARRIER_UP: - printf("Carrier up\n"); - break; - case PUTBIT_CARRIER_DOWN: - printf("Carrier down\n"); - break; - default: - printf("Eh! - %d\n", status); - break; } return 0; } @@ -192,18 +176,7 @@ static void v17putbit(void *user_data, int bit) static int v17_tx_status(void *user_data, int status) { - switch (status) - { - case MODEM_TX_STATUS_DATA_EXHAUSTED: - printf("V.17 tx data exhausted\n"); - break; - case MODEM_TX_STATUS_SHUTDOWN_COMPLETE: - printf("V.17 tx shutdown complete\n"); - break; - default: - printf("V.17 tx status is %d\n", status); - break; - } + printf("V.17 tx status is %s (%d)\n", signal_status_to_str(status), status); return 0; } /*- End of function --------------------------------------------------------*/ @@ -460,8 +433,8 @@ int main(int argc, char *argv[]) /* Note that we might get a few bad bits as the carrier shuts down. */ bert_result(&bert, &bert_results); - fprintf(stderr, "Final result %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); - fprintf(stderr, "Last report %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs); + fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); + fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs); /* See if bit errors are appearing yet. Also check we are getting enough bits out of the receiver. The last regular report should be error free, though the final report will generally contain bits errors as the carrier was dying. The total number of bits out of the receiver should be at least the number we sent. Also, since BERT sync should have occurred @@ -516,8 +489,8 @@ int main(int argc, char *argv[]) { bert_result(&bert, &bert_results); fprintf(stderr, "At completion:\n"); - fprintf(stderr, "Final result %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); - fprintf(stderr, "Last report %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs); + fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); + fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs); one_way_line_model_release(line_model); if (signal_level > -43) diff --git a/libs/spandsp/tests/v22bis_tests.c b/libs/spandsp/tests/v22bis_tests.c index 5a2cd0bf32..e01ff03777 100644 --- a/libs/spandsp/tests/v22bis_tests.c +++ b/libs/spandsp/tests/v22bis_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: v22bis_tests.c,v 1.51 2008/08/16 14:59:50 steveu Exp $ + * $Id: v22bis_tests.c,v 1.52 2008/09/07 12:45:17 steveu Exp $ */ /*! \page v22bis_tests_page V.22bis modem tests @@ -108,30 +108,15 @@ static void v22bis_putbit(void *user_data, int bit) if (bit < 0) { /* Special conditions */ + printf("V.22bis rx status is %s (%d)\n", signal_status_to_str(bit), bit); switch (bit) { - case PUTBIT_TRAINING_FAILED: - printf("Training failed\n"); - break; - case PUTBIT_TRAINING_IN_PROGRESS: - printf("Training in progress\n"); - break; - case PUTBIT_TRAINING_SUCCEEDED: - printf("Training succeeded\n"); + case SIG_STATUS_TRAINING_SUCCEEDED: len = v22bis_equalizer_state(s, &coeffs); printf("Equalizer:\n"); for (i = 0; i < len; i++) printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); break; - case PUTBIT_CARRIER_UP: - printf("Carrier up\n"); - break; - case PUTBIT_CARRIER_DOWN: - printf("Carrier down\n"); - break; - default: - printf("Eh! - %d\n", bit); - break; } return; } diff --git a/libs/spandsp/tests/v27ter_tests.c b/libs/spandsp/tests/v27ter_tests.c index 5ada42a7cb..2f1d8fdddb 100644 --- a/libs/spandsp/tests/v27ter_tests.c +++ b/libs/spandsp/tests/v27ter_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: v27ter_tests.c,v 1.91 2008/08/29 09:28:13 steveu Exp $ + * $Id: v27ter_tests.c,v 1.93 2008/09/07 06:39:52 steveu Exp $ */ /*! \page v27ter_tests_page V.27ter modem tests @@ -132,28 +132,7 @@ static void reporter(void *user_data, int reason, bert_results_t *results) static int v27ter_rx_status(void *user_data, int status) { - printf("V.27ter rx status is %d\n", status); - switch (status) - { - case PUTBIT_TRAINING_FAILED: - printf("Training failed\n"); - break; - case PUTBIT_TRAINING_IN_PROGRESS: - printf("Training in progress\n"); - break; - case PUTBIT_TRAINING_SUCCEEDED: - printf("Training succeeded\n"); - break; - case PUTBIT_CARRIER_UP: - printf("Carrier up\n"); - break; - case PUTBIT_CARRIER_DOWN: - printf("Carrier down\n"); - break; - default: - printf("Eh! - %d\n", status); - break; - } + printf("V.27ter rx status is %s (%d)\n", signal_status_to_str(status), status); return 0; } /*- End of function --------------------------------------------------------*/ @@ -174,18 +153,7 @@ static void v27terputbit(void *user_data, int bit) static int v27ter_tx_status(void *user_data, int status) { - switch (status) - { - case MODEM_TX_STATUS_DATA_EXHAUSTED: - printf("V.27ter tx data exhausted\n"); - break; - case MODEM_TX_STATUS_SHUTDOWN_COMPLETE: - printf("V.27ter tx shutdown complete\n"); - break; - default: - printf("V.27ter tx status is %d\n", status); - break; - } + printf("V.27ter tx status is %s (%d)\n", signal_status_to_str(status), status); return 0; } /*- End of function --------------------------------------------------------*/ @@ -457,8 +425,8 @@ int main(int argc, char *argv[]) /* Note that we might get a few bad bits as the carrier shuts down. */ bert_result(&bert, &bert_results); - fprintf(stderr, "Final result %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); - fprintf(stderr, "Last report %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs); + fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); + fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs); /* See if bit errors are appearing yet. Also check we are getting enough bits out of the receiver. The last regular report should be error free, though the final report will generally contain bits errors as the carrier was dying. The total number of bits out of the receiver should be at least the number we sent. Also, since BERT sync should have occurred @@ -506,15 +474,13 @@ int main(int argc, char *argv[]) line_model_monitor_line_spectrum_update(amp, samples); #endif v27ter_rx(&rx, amp, samples); - if (decode_test_file == NULL && block%500 == 0) - printf("Noise level is %d\n", noise_level); } if (!decode_test_file) { bert_result(&bert, &bert_results); fprintf(stderr, "At completion:\n"); - fprintf(stderr, "Final result %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); - fprintf(stderr, "Last report %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs); + fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); + fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs); one_way_line_model_release(line_model); if (signal_level > -43) { diff --git a/libs/spandsp/tests/v29_tests.c b/libs/spandsp/tests/v29_tests.c index d454a550b1..735946db9a 100644 --- a/libs/spandsp/tests/v29_tests.c +++ b/libs/spandsp/tests/v29_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: v29_tests.c,v 1.102 2008/08/29 09:28:13 steveu Exp $ + * $Id: v29_tests.c,v 1.106 2008/09/07 12:45:17 steveu Exp $ */ /*! \page v29_tests_page V.29 modem tests @@ -134,33 +134,29 @@ static int v29_rx_status(void *user_data, int status) v29_rx_state_t *rx; int i; int len; +#if defined(SPANDSP_USE_FIXED_POINT) + complexi16_t *coeffs; +#else complexf_t *coeffs; +#endif - printf("V.29 rx status is %d\n", status); + printf("V.29 rx status is %s (%d)\n", signal_status_to_str(status), status); rx = (v29_rx_state_t *) user_data; switch (status) { - case PUTBIT_TRAINING_FAILED: - printf("Training failed\n"); - break; - case PUTBIT_TRAINING_IN_PROGRESS: - printf("Training in progress\n"); - break; - case PUTBIT_TRAINING_SUCCEEDED: + case SIG_STATUS_TRAINING_SUCCEEDED: printf("Training succeeded\n"); +#if defined(SPANDSP_USE_FIXED_POINT) + len = v29_rx_equalizer_state(rx, &coeffs); + printf("Equalizer:\n"); + for (i = 0; i < len; i++) + printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/4096.0f, coeffs[i].im/4096.0f); +#else len = v29_rx_equalizer_state(rx, &coeffs); printf("Equalizer:\n"); for (i = 0; i < len; i++) printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i])); - break; - case PUTBIT_CARRIER_UP: - printf("Carrier up\n"); - break; - case PUTBIT_CARRIER_DOWN: - printf("Carrier down\n"); - break; - default: - printf("Eh! - %d\n", status); +#endif break; } return 0; @@ -187,18 +183,7 @@ static void v29putbit(void *user_data, int bit) static int v29_tx_status(void *user_data, int status) { - switch (status) - { - case MODEM_TX_STATUS_DATA_EXHAUSTED: - printf("V.29 tx data exhausted\n"); - break; - case MODEM_TX_STATUS_SHUTDOWN_COMPLETE: - printf("V.29 tx shutdown complete\n"); - break; - default: - printf("V.29 tx status is %d\n", status); - break; - } + printf("V.29 tx status is %s (%d)\n", signal_status_to_str(status), status); return 0; } /*- End of function --------------------------------------------------------*/ @@ -213,7 +198,11 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex { int i; int len; +#if defined(SPANDSP_USE_FIXED_POINT) + complexi16_t *coeffs; +#else complexf_t *coeffs; +#endif float fpower; v29_rx_state_t *rx; static float smooth_power = 0.0f; @@ -249,6 +238,16 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex symbol_no++; if (--update_interval <= 0) { +#if defined(SPANDSP_USE_FIXED_POINT) + len = v29_rx_equalizer_state(rx, &coeffs); + printf("Equalizer A:\n"); + for (i = 0; i < len; i++) + printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/4096.0f, coeffs[i].im/4096.0f); +#if defined(ENABLE_GUI) + if (use_gui) + qam_monitor_update_int_equalizer(qam_monitor, coeffs, len); +#endif +#else len = v29_rx_equalizer_state(rx, &coeffs); printf("Equalizer A:\n"); for (i = 0; i < len; i++) @@ -256,6 +255,7 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex #if defined(ENABLE_GUI) if (use_gui) qam_monitor_update_equalizer(qam_monitor, coeffs, len); +#endif #endif update_interval = 100; } @@ -451,8 +451,8 @@ int main(int argc, char *argv[]) /* Note that we might get a few bad bits as the carrier shuts down. */ bert_result(&bert, &bert_results); - fprintf(stderr, "Final result %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); - fprintf(stderr, "Last report %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs); + fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); + fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs); /* See if bit errors are appearing yet. Also check we are getting enough bits out of the receiver. The last regular report should be error free, though the final report will generally contain bits errors as the carrier was dying. The total number of bits out of the receiver should be at least the number we sent. Also, since BERT sync should have occurred @@ -500,15 +500,13 @@ int main(int argc, char *argv[]) line_model_monitor_line_spectrum_update(amp, samples); #endif v29_rx(&rx, amp, samples); - if (decode_test_file == NULL && block%500 == 0) - printf("Noise level is %d\n", noise_level); } if (!decode_test_file) { bert_result(&bert, &bert_results); fprintf(stderr, "At completion:\n"); - fprintf(stderr, "Final result %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); - fprintf(stderr, "Last report %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs); + fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); + fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs); one_way_line_model_release(line_model); if (signal_level > -43)