From b11b19af93c9de9c452c3d5bfa6c63392a5f4104 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 20 Feb 2009 18:28:09 +0000 Subject: [PATCH] update to snapshot spandsp-20090216 git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12188 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- libs/spandsp/src/Makefile.am | 3 +- libs/spandsp/src/fax.c | 45 +-- libs/spandsp/src/fax_modems.c | 289 ++++++++++++++++++ libs/spandsp/src/libspandsp.dsp | 4 + libs/spandsp/src/libspandsp.vcproj | 1 + libs/spandsp/src/modem_connect_tones.c | 4 +- libs/spandsp/src/spandsp/fax_modems.h | 32 +- libs/spandsp/src/spandsp/private/fax_modems.h | 4 +- libs/spandsp/src/spandsp/private/t4.h | 6 +- libs/spandsp/src/spandsp/version.h | 4 +- libs/spandsp/src/t31.c | 46 +-- libs/spandsp/src/t38_gateway.c | 57 ++-- libs/spandsp/src/t4.c | 22 +- 13 files changed, 397 insertions(+), 120 deletions(-) create mode 100644 libs/spandsp/src/fax_modems.c diff --git a/libs/spandsp/src/Makefile.am b/libs/spandsp/src/Makefile.am index ce163a25fb..eab1d2bd38 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.123 2009/02/10 17:16:57 steveu Exp $ +## $Id: Makefile.am,v 1.124 2009/02/14 15:21:14 steveu Exp $ AM_CFLAGS = $(COMP_VENDOR_CFLAGS) AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS) @@ -65,6 +65,7 @@ libspandsp_la_SOURCES = adsi.c \ dtmf.c \ echo.c \ fax.c \ + fax_modems.c \ fsk.c \ g711.c \ g722.c \ diff --git a/libs/spandsp/src/fax.c b/libs/spandsp/src/fax.c index 03e6c0be37..ca3cbc6844 100644 --- a/libs/spandsp/src/fax.c +++ b/libs/spandsp/src/fax.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: fax.c,v 1.86 2009/02/10 13:06:46 steveu Exp $ + * $Id: fax.c,v 1.88 2009/02/16 09:57:22 steveu Exp $ */ /*! \file */ @@ -223,38 +223,6 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len) } /*- End of function --------------------------------------------------------*/ -static void fax_fax_modems_init(fax_modems_state_t *s, int use_tep, void *user_data) -{ - s->use_tep = use_tep; - - hdlc_rx_init(&s->hdlc_rx, FALSE, FALSE, HDLC_FRAMING_OK_THRESHOLD, t30_hdlc_accept, user_data); - hdlc_tx_init(&s->hdlc_tx, FALSE, 2, FALSE, hdlc_underflow_handler, user_data); - fsk_rx_init(&s->v21_rx, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &s->hdlc_rx); - fsk_rx_signal_cutoff(&s->v21_rx, -45.5); - fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx); - v17_rx_init(&s->v17_rx, 14400, t30_non_ecm_put_bit, user_data); - v17_tx_init(&s->v17_tx, 14400, s->use_tep, t30_non_ecm_get_bit, user_data); - v29_rx_init(&s->v29_rx, 9600, t30_non_ecm_put_bit, user_data); - v29_rx_signal_cutoff(&s->v29_rx, -45.5); - v29_tx_init(&s->v29_tx, 9600, s->use_tep, t30_non_ecm_get_bit, user_data); - v27ter_rx_init(&s->v27ter_rx, 4800, t30_non_ecm_put_bit, user_data); - v27ter_tx_init(&s->v27ter_tx, 4800, s->use_tep, t30_non_ecm_get_bit, user_data); - silence_gen_init(&s->silence_gen, 0); - modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG); - modem_connect_tones_rx_init(&s->connect_rx, - MODEM_CONNECT_TONES_FAX_CNG, - tone_detected, - user_data); - dc_restore_init(&s->dc_restore); - - s->rx_signal_present = FALSE; - s->rx_handler = (span_rx_handler_t *) &span_dummy_rx; - s->rx_user_data = NULL; - s->tx_handler = (span_tx_handler_t *) &silence_gen; - s->tx_user_data = &s->silence_gen; -} -/*- End of function --------------------------------------------------------*/ - SPAN_DECLARE(int) fax_rx(fax_state_t *s, int16_t *amp, int len) { int i; @@ -371,7 +339,7 @@ static void fax_set_rx_type(void *user_data, int type, int bit_rate, int short_t { case T30_MODEM_V21: fsk_rx_init(&t->v21_rx, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, put_bit_user_data); - fsk_rx_signal_cutoff(&t->v21_rx, -45.5); + fsk_rx_signal_cutoff(&t->v21_rx, -45.5f); t->rx_handler = (span_rx_handler_t *) &fsk_rx; t->rx_user_data = &t->v21_rx; break; @@ -548,7 +516,14 @@ SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party) memset(s, 0, sizeof(*s)); span_log_init(&s->logging, SPAN_LOG_NONE, NULL); span_log_set_protocol(&s->logging, "FAX"); - fax_fax_modems_init(&s->modems, FALSE, &s->t30); + fax_modems_init(&s->modems, + FALSE, + t30_hdlc_accept, + hdlc_underflow_handler, + t30_non_ecm_put_bit, + t30_non_ecm_get_bit, + tone_detected, + &s->t30); t30_init(&s->t30, calling_party, fax_set_rx_type, diff --git a/libs/spandsp/src/fax_modems.c b/libs/spandsp/src/fax_modems.c new file mode 100644 index 0000000000..b919f75654 --- /dev/null +++ b/libs/spandsp/src/fax_modems.c @@ -0,0 +1,289 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * fax_modems.c - the analogue modem set for fax processing + * + * Written by Steve Underwood + * + * Copyright (C) 2003, 2005, 2006, 2008 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: fax_modems.c,v 1.2 2009/02/16 09:57:22 steveu Exp $ + */ + +/*! \file */ + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include +#include +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif +#include "floating_fudge.h" +#include +#include +#include +#if defined(LOG_FAX_AUDIO) +#include +#endif + +#include "spandsp/telephony.h" +#include "spandsp/logging.h" +#include "spandsp/bit_operations.h" +#include "spandsp/dc_restore.h" +#include "spandsp/queue.h" +#include "spandsp/power_meter.h" +#include "spandsp/complex.h" +#include "spandsp/tone_detect.h" +#include "spandsp/tone_generate.h" +#include "spandsp/async.h" +#include "spandsp/crc.h" +#include "spandsp/hdlc.h" +#include "spandsp/silence_gen.h" +#include "spandsp/fsk.h" +#include "spandsp/v29tx.h" +#include "spandsp/v29rx.h" +#include "spandsp/v27ter_tx.h" +#include "spandsp/v27ter_rx.h" +#include "spandsp/v17tx.h" +#include "spandsp/v17rx.h" +#include "spandsp/super_tone_rx.h" +#include "spandsp/modem_connect_tones.h" +#include "spandsp/fax_modems.h" + +#include "spandsp/private/logging.h" +#include "spandsp/private/fsk.h" +#include "spandsp/private/v17tx.h" +#include "spandsp/private/v17rx.h" +#include "spandsp/private/v27ter_tx.h" +#include "spandsp/private/v27ter_rx.h" +#include "spandsp/private/v29tx.h" +#include "spandsp/private/v29rx.h" +#include "spandsp/private/modem_connect_tones.h" +#include "spandsp/private/hdlc.h" +#include "spandsp/private/fax_modems.h" + +#define HDLC_FRAMING_OK_THRESHOLD 5 + +int fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], int len) +{ + fax_modems_state_t *s; + + s = (fax_modems_state_t *) user_data; + v17_rx(&s->v17_rx, amp, len); + fsk_rx(&s->v21_rx, amp, len); + if (s->rx_frame_received) + { + /* We have received something, and the fast modem has not trained. We must + be receiving valid V.21 */ + span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); + s->rx_handler = (span_rx_handler_t *) &fsk_rx; + s->rx_user_data = &s->v21_rx; + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[], int len) +{ + fax_modems_state_t *s; + + s = (fax_modems_state_t *) user_data; + v27ter_rx(&s->v27ter_rx, amp, len); + fsk_rx(&s->v21_rx, amp, len); + if (s->rx_frame_received) + { + /* We have received something, and the fast modem has not trained. We must + be receiving valid V.21 */ + span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); + s->rx_handler = (span_rx_handler_t *) &fsk_rx; + s->rx_user_data = &s->v21_rx; + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], int len) +{ + fax_modems_state_t *s; + + s = (fax_modems_state_t *) user_data; + v29_rx(&s->v29_rx, amp, len); + fsk_rx(&s->v21_rx, amp, len); + if (s->rx_frame_received) + { + /* We have received something, and the fast modem has not trained. We must + be receiving valid V.21 */ + span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx)); + s->rx_handler = (span_rx_handler_t *) &fsk_rx; + s->rx_user_data = &s->v21_rx; + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static void v21_rx_status_handler(void *user_data, int status) +{ + fax_modems_state_t *s; + + s = (fax_modems_state_t *) user_data; +} +/*- End of function --------------------------------------------------------*/ + +static void v17_rx_status_handler(void *user_data, int status) +{ + fax_modems_state_t *s; + + s = (fax_modems_state_t *) user_data; + switch (status) + { + case SIG_STATUS_TRAINING_SUCCEEDED: + span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->v17_rx)); + s->rx_handler = (span_rx_handler_t *) &v17_rx; + s->rx_user_data = &s->v17_rx; + break; + } +} +/*- End of function --------------------------------------------------------*/ + +static void v27ter_rx_status_handler(void *user_data, int status) +{ + fax_modems_state_t *s; + + s = (fax_modems_state_t *) user_data; + switch (status) + { + case SIG_STATUS_TRAINING_SUCCEEDED: + span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->v27ter_rx)); + s->rx_handler = (span_rx_handler_t *) &v27ter_rx; + s->rx_user_data = &s->v27ter_rx; + break; + } +} +/*- End of function --------------------------------------------------------*/ + +static void v29_rx_status_handler(void *user_data, int status) +{ + fax_modems_state_t *s; + + s = (fax_modems_state_t *) user_data; + switch (status) + { + case SIG_STATUS_TRAINING_SUCCEEDED: + span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->v29_rx)); + s->rx_handler = (span_rx_handler_t *) &v29_rx; + s->rx_user_data = &s->v29_rx; + break; + } +} +/*- End of function --------------------------------------------------------*/ + +void start_fax_modems_rx_modem(fax_modems_state_t *s, int which) +{ + switch (which) + { + case FAX_MODEM_V17_RX: + v17_rx_set_modem_status_handler(&s->v17_rx, v17_rx_status_handler, s); + break; + case FAX_MODEM_V27TER_RX: + v27ter_rx_set_modem_status_handler(&s->v27ter_rx, v27ter_rx_status_handler, s); + break; + case FAX_MODEM_V29_RX: + v29_rx_set_modem_status_handler(&s->v29_rx, v29_rx_status_handler, s); + break; + } + fsk_rx_set_modem_status_handler(&s->v21_rx, v21_rx_status_handler, s); +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(void) fax_modems_set_tep_mode(fax_modems_state_t *s, int use_tep) +{ + s->use_tep = use_tep; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s, + int use_tep, + hdlc_frame_handler_t hdlc_accept, + hdlc_underflow_handler_t hdlc_tx_underflow, + put_bit_func_t non_ecm_put_bit, + get_bit_func_t non_ecm_get_bit, + tone_report_func_t tone_callback, + void *user_data) +{ + if (s == NULL) + { + if ((s = (fax_modems_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + memset(s, 0, sizeof(*s)); + s->use_tep = use_tep; + + hdlc_rx_init(&s->hdlc_rx, FALSE, FALSE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept, user_data); + hdlc_tx_init(&s->hdlc_tx, FALSE, 2, FALSE, hdlc_tx_underflow, user_data); + fsk_rx_init(&s->v21_rx, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &s->hdlc_rx); + fsk_rx_signal_cutoff(&s->v21_rx, -39.09f); + fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx); + v17_rx_init(&s->v17_rx, 14400, non_ecm_put_bit, user_data); + v17_tx_init(&s->v17_tx, 14400, s->use_tep, non_ecm_get_bit, user_data); + v29_rx_init(&s->v29_rx, 9600, non_ecm_put_bit, user_data); + v29_rx_signal_cutoff(&s->v29_rx, -45.5f); + v29_tx_init(&s->v29_tx, 9600, s->use_tep, non_ecm_get_bit, user_data); + v27ter_rx_init(&s->v27ter_rx, 4800, non_ecm_put_bit, user_data); + v27ter_tx_init(&s->v27ter_tx, 4800, s->use_tep, non_ecm_get_bit, user_data); + silence_gen_init(&s->silence_gen, 0); + modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG); + if (tone_callback) + { + modem_connect_tones_rx_init(&s->connect_rx, + MODEM_CONNECT_TONES_FAX_CNG, + tone_callback, + user_data); + } + dc_restore_init(&s->dc_restore); + + s->rx_signal_present = FALSE; + s->rx_handler = (span_rx_handler_t *) &span_dummy_rx; + s->rx_user_data = NULL; + s->tx_handler = (span_tx_handler_t *) &silence_gen; + s->tx_user_data = &s->silence_gen; + return s; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) fax_modems_release(fax_modems_state_t *s) +{ + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) fax_modems_free(fax_modems_state_t *s) +{ + if (s) + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/src/libspandsp.dsp b/libs/spandsp/src/libspandsp.dsp index bc7855109e..3befb1ba2d 100644 --- a/libs/spandsp/src/libspandsp.dsp +++ b/libs/spandsp/src/libspandsp.dsp @@ -161,6 +161,10 @@ SOURCE=.\fax.c # End Source File # Begin Source File +SOURCE=.\fax_modems.c +# End Source File +# Begin Source File + SOURCE=.\fsk.c # End Source File # Begin Source File diff --git a/libs/spandsp/src/libspandsp.vcproj b/libs/spandsp/src/libspandsp.vcproj index 6f2d6cb9cf..56c5f9bfe2 100644 --- a/libs/spandsp/src/libspandsp.vcproj +++ b/libs/spandsp/src/libspandsp.vcproj @@ -105,6 +105,7 @@ + diff --git a/libs/spandsp/src/modem_connect_tones.c b/libs/spandsp/src/modem_connect_tones.c index 4b611db2ac..1e1566b4f6 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.34 2009/02/10 13:06:46 steveu Exp $ + * $Id: modem_connect_tones.c,v 1.35 2009/02/16 09:57:22 steveu Exp $ */ /*! \file */ @@ -522,7 +522,7 @@ SPAN_DECLARE(modem_connect_tones_rx_state_t *) modem_connect_tones_rx_init(modem { case MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE: fsk_rx_init(&(s->v21rx), &preset_fsk_specs[FSK_V21CH2], TRUE, v21_put_bit, s); - fsk_rx_signal_cutoff(&(s->v21rx), -45.5); + fsk_rx_signal_cutoff(&(s->v21rx), -45.5f); break; case MODEM_CONNECT_TONES_ANS_PR: case MODEM_CONNECT_TONES_ANSAM: diff --git a/libs/spandsp/src/spandsp/fax_modems.h b/libs/spandsp/src/spandsp/fax_modems.h index 80b7b2ca7a..86c5d5d294 100644 --- a/libs/spandsp/src/spandsp/fax_modems.h +++ b/libs/spandsp/src/spandsp/fax_modems.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: fax_modems.h,v 1.9 2009/02/10 13:06:47 steveu Exp $ + * $Id: fax_modems.h,v 1.10 2009/02/14 15:21:14 steveu Exp $ */ /*! \file */ @@ -30,6 +30,25 @@ #if !defined(_SPANDSP_FAX_MODEMS_H_) #define _SPANDSP_FAX_MODEMS_H_ +enum +{ + FAX_MODEM_NONE = -1, + FAX_MODEM_FLUSH = 0, + FAX_MODEM_SILENCE_TX, + FAX_MODEM_SILENCE_RX, + FAX_MODEM_CED_TONE, + FAX_MODEM_CNG_TONE, + FAX_MODEM_NOCNG_TONE, + FAX_MODEM_V21_TX, + FAX_MODEM_V17_TX, + FAX_MODEM_V27TER_TX, + FAX_MODEM_V29_TX, + FAX_MODEM_V21_RX, + FAX_MODEM_V17_RX, + FAX_MODEM_V27TER_RX, + FAX_MODEM_V29_RX +}; + /*! The set of modems needed for FAX, plus the auxilliary stuff, like tone generation. */ @@ -45,7 +64,16 @@ SPAN_DECLARE(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], in SPAN_DECLARE(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[], int len); SPAN_DECLARE(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], int len); -SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s, void *user_data); +SPAN_DECLARE(void) fax_modems_set_tep_mode(fax_modems_state_t *s, int use_tep); + +SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s, + int use_tep, + hdlc_frame_handler_t hdlc_accept, + hdlc_underflow_handler_t hdlc_tx_underflow, + put_bit_func_t non_ecm_put_bit, + get_bit_func_t non_ecm_get_bit, + tone_report_func_t tone_callback, + void *user_data); SPAN_DECLARE(int) fax_modems_release(fax_modems_state_t *s); diff --git a/libs/spandsp/src/spandsp/private/fax_modems.h b/libs/spandsp/src/spandsp/private/fax_modems.h index 02b856dfbf..042194ba11 100644 --- a/libs/spandsp/src/spandsp/private/fax_modems.h +++ b/libs/spandsp/src/spandsp/private/fax_modems.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: fax_modems.h,v 1.1 2008/10/13 13:14:01 steveu Exp $ + * $Id: fax_modems.h,v 1.2 2009/02/14 15:21:14 steveu Exp $ */ /*! \file */ @@ -90,6 +90,8 @@ struct fax_modems_state_s int rx_signal_present; /*! \brief TRUE if a modem has trained correctly. */ int rx_trained; + /*! \brief TRUE if an HDLC frame has been received correctly. */ + int rx_frame_received; /*! The current receive signal handler */ span_rx_handler_t *rx_handler; diff --git a/libs/spandsp/src/spandsp/private/t4.h b/libs/spandsp/src/spandsp/private/t4.h index 926ed2d9ac..df84f4b809 100644 --- a/libs/spandsp/src/spandsp/private/t4.h +++ b/libs/spandsp/src/spandsp/private/t4.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: t4.h,v 1.2 2009/02/05 12:21:36 steveu Exp $ + * $Id: t4.h,v 1.3 2009/02/16 09:57:22 steveu Exp $ */ #if !defined(_SPANDSP_PRIVATE_T4_H_) @@ -40,6 +40,10 @@ typedef struct int output_compression; /*! \brief The TIFF G3 FAX options. */ int output_t4_options; + /*! \brief The TIFF photometric setting for the current page. */ + uint16_t photo_metric; + /*! \brief The TIFF fill order setting for the current page. */ + uint16_t fill_order; /* "Background" information about the FAX, which can be stored in the image file. */ /*! \brief The vendor of the machine which produced the file. */ diff --git a/libs/spandsp/src/spandsp/version.h b/libs/spandsp/src/spandsp/version.h index a2f63979da..6cd666fe9f 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 20090212 -#define SPANDSP_RELEASE_TIME 142337 +#define SPANDSP_RELEASE_DATE 20090216 +#define SPANDSP_RELEASE_TIME 100031 #endif /*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/src/t31.c b/libs/spandsp/src/t31.c index be2390614c..5fcc7ef705 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.142 2009/02/12 14:14:58 steveu Exp $ + * $Id: t31.c,v 1.144 2009/02/16 09:57:22 steveu Exp $ */ /*! \file */ @@ -1504,11 +1504,11 @@ static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int static void t31_v21_rx(t31_state_t *s) { - hdlc_rx_init(&(s->audio.modems.hdlc_rx), FALSE, TRUE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept_frame, s); s->at_state.ok_is_pending = FALSE; s->hdlc_tx.final = FALSE; s->hdlc_tx.len = 0; s->dled = FALSE; + hdlc_rx_init(&(s->audio.modems.hdlc_rx), FALSE, TRUE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept_frame, s); fsk_rx_init(&(s->audio.modems.v21_rx), &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &(s->audio.modems.hdlc_rx)); fsk_rx_signal_cutoff(&(s->audio.modems.v21_rx), -39.09f); s->at_state.transmit = TRUE; @@ -2292,39 +2292,6 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len) } /*- End of function --------------------------------------------------------*/ -static fax_modems_state_t *t31_fax_modems_init(fax_modems_state_t *s, int use_tep, void *user_data) -{ - s->use_tep = use_tep; - - hdlc_rx_init(&s->hdlc_rx, FALSE, TRUE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept_frame, user_data); - hdlc_tx_init(&s->hdlc_tx, FALSE, 2, FALSE, hdlc_tx_underflow, user_data); - fsk_rx_init(&s->v21_rx, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &s->hdlc_rx); - fsk_rx_signal_cutoff(&s->v21_rx, -39.09f); - fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx); - v17_rx_init(&s->v17_rx, 14400, non_ecm_put_bit, user_data); - v17_tx_init(&s->v17_tx, 14400, s->use_tep, non_ecm_get_bit, user_data); - v29_rx_init(&s->v29_rx, 9600, non_ecm_put_bit, user_data); - v29_rx_signal_cutoff(&s->v29_rx, -45.5); - v29_tx_init(&s->v29_tx, 9600, s->use_tep, non_ecm_get_bit, user_data); - v27ter_rx_init(&s->v27ter_rx, 4800, non_ecm_put_bit, user_data); - v27ter_tx_init(&s->v27ter_tx, 4800, s->use_tep, non_ecm_get_bit, user_data); - silence_gen_init(&s->silence_gen, 0); - modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG); - modem_connect_tones_rx_init(&s->connect_rx, - MODEM_CONNECT_TONES_FAX_CNG, - tone_detected, - user_data); - dc_restore_init(&s->dc_restore); - - s->rx_signal_present = FALSE; - s->rx_handler = (span_rx_handler_t *) &span_dummy_rx; - s->rx_user_data = NULL; - s->tx_handler = (span_tx_handler_t *) &silence_gen; - s->tx_user_data = &s->silence_gen; - return s; -} -/*- End of function --------------------------------------------------------*/ - SPAN_DECLARE(int) t31_rx(t31_state_t *s, int16_t amp[], int len) { int i; @@ -2537,7 +2504,14 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s, s->modem_control_handler = modem_control_handler; s->modem_control_user_data = modem_control_user_data; - t31_fax_modems_init(&s->audio.modems, FALSE, s); + fax_modems_init(&s->audio.modems, + FALSE, + hdlc_accept_frame, + hdlc_tx_underflow, + non_ecm_put_bit, + non_ecm_get_bit, + tone_detected, + (void *) s); power_meter_init(&(s->audio.rx_power), 4); s->audio.last_sample = 0; s->audio.silence_threshold_power = power_meter_level_dbm0(-36); diff --git a/libs/spandsp/src/t38_gateway.c b/libs/spandsp/src/t38_gateway.c index d591c26422..aaeb221481 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.155 2009/02/12 12:38:39 steveu Exp $ + * $Id: t38_gateway.c,v 1.157 2009/02/16 09:57:22 steveu Exp $ */ /*! \file */ @@ -277,42 +277,6 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len) } /*- End of function --------------------------------------------------------*/ -static void t38_fax_modems_init(fax_modems_state_t *s, int use_tep, void *user_data) -{ - s->use_tep = use_tep; - - hdlc_rx_init(&s->hdlc_rx, FALSE, TRUE, HDLC_FRAMING_OK_THRESHOLD, NULL, user_data); - hdlc_tx_init(&s->hdlc_tx, FALSE, 2, TRUE, hdlc_underflow_handler, user_data); - fsk_rx_init(&s->v21_rx, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) t38_hdlc_rx_put_bit, &s->hdlc_rx); -#if 0 - fsk_rx_signal_cutoff(&s->v21_rx, -45.5); -#endif - fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx); - v17_rx_init(&s->v17_rx, 14400, non_ecm_put_bit, user_data); - v17_tx_init(&s->v17_tx, 14400, s->use_tep, t38_non_ecm_buffer_get_bit, user_data); - v29_rx_init(&s->v29_rx, 9600, non_ecm_put_bit, user_data); -#if 0 - v29_rx_signal_cutoff(&s->v29_rx, -45.5); -#endif - v29_tx_init(&s->v29_tx, 9600, s->use_tep, t38_non_ecm_buffer_get_bit, user_data); - v27ter_rx_init(&s->v27ter_rx, 4800, non_ecm_put_bit, user_data); - v27ter_tx_init(&s->v27ter_tx, 4800, s->use_tep, t38_non_ecm_buffer_get_bit, user_data); - silence_gen_init(&s->silence_gen, 0); - modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG); - modem_connect_tones_rx_init(&s->connect_rx, - MODEM_CONNECT_TONES_FAX_CNG, - tone_detected, - user_data); - dc_restore_init(&s->dc_restore); - - s->rx_signal_present = FALSE; - s->rx_handler = (span_rx_handler_t *) &span_dummy_rx; - s->rx_user_data = NULL; - s->tx_handler = (span_tx_handler_t *) &silence_gen; - s->tx_user_data = &s->silence_gen; -} -/*- End of function --------------------------------------------------------*/ - static void tone_detected(void *user_data, int on, int level, int delay) { t38_gateway_state_t *s; @@ -1971,7 +1935,7 @@ static int restart_rx_modem(t38_gateway_state_t *s) s->t38x.current_tx_data_type = T38_DATA_V21; fsk_rx_init(&(s->audio.modems.v21_rx), &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) t38_hdlc_rx_put_bit, &(s->audio.modems.hdlc_rx)); #if 0 - fsk_rx_signal_cutoff(&(s->audio.modems.v21_rx), -45.5); + fsk_rx_signal_cutoff(&(s->audio.modems.v21_rx), -45.5f); #endif if (s->core.image_data_mode && s->core.ecm_mode) { @@ -2187,7 +2151,22 @@ SPAN_DECLARE(void) t38_gateway_set_real_time_frame_handler(t38_gateway_state_t * static int t38_gateway_audio_init(t38_gateway_state_t *s) { - t38_fax_modems_init(&s->audio.modems, FALSE, s); + fax_modems_init(&s->audio.modems, + FALSE, + NULL, + hdlc_underflow_handler, + non_ecm_put_bit, + t38_non_ecm_buffer_get_bit, + tone_detected, + s); + /* We need to use progressive HDLC transmit, and a special HDLC receiver, which is different + from the other uses of FAX modems. */ + hdlc_tx_init(&s->audio.modems.hdlc_tx, FALSE, 2, TRUE, hdlc_underflow_handler, s); + fsk_rx_set_put_bit(&s->audio.modems.v21_rx, (put_bit_func_t) t38_hdlc_rx_put_bit, &s->audio.modems.hdlc_rx); + /* TODO: Don't use the very low cutoff levels we would like to. We get some quirks if we do. + We need to sort this out. */ + fsk_rx_signal_cutoff(&s->audio.modems.v21_rx, -30.0f); + v29_rx_signal_cutoff(&s->audio.modems.v29_rx, -28.5f); return 0; } /*- End of function --------------------------------------------------------*/ diff --git a/libs/spandsp/src/t4.c b/libs/spandsp/src/t4.c index 06b3ac9052..9ff65867ea 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.124 2009/02/10 13:06:46 steveu Exp $ + * $Id: t4.c,v 1.125 2009/02/16 09:57:22 steveu Exp $ */ /* @@ -301,6 +301,8 @@ static int get_tiff_directory_info(t4_state_t *s) { -1.00f, -1, -1} }; uint16_t res_unit; + uint16_t photo_metric; + uint16_t fill_order; uint32_t parm; float x_resolution; float y_resolution; @@ -325,6 +327,16 @@ static int get_tiff_directory_info(t4_state_t *s) TIFFGetField(t->tiff_file, TIFFTAG_YRESOLUTION, &y_resolution); res_unit = RESUNIT_INCH; TIFFGetField(t->tiff_file, TIFFTAG_RESOLUTIONUNIT, &res_unit); + photo_metric = PHOTOMETRIC_MINISWHITE; + TIFFGetField(t->tiff_file, TIFFTAG_PHOTOMETRIC, &photo_metric); + if (photo_metric != PHOTOMETRIC_MINISWHITE) + span_log(&s->logging, SPAN_LOG_FLOW, "%s: Photometric needs swapping.\n", s->file); + t->photo_metric = photo_metric; + fill_order = FILLORDER_LSB2MSB; + TIFFGetField(t->tiff_file, TIFFTAG_FILLORDER, &fill_order); + if (fill_order != FILLORDER_LSB2MSB) + span_log(&s->logging, SPAN_LOG_FLOW, "%s: Fill order needs swapping.\n", s->file); + t->fill_order = fill_order; /* Allow a little range for the X resolution in centimeters. The spec doesn't pin down the precise value. The other value should be exact. */ @@ -384,6 +396,7 @@ static int read_tiff_image(t4_state_t *s) { int row; int image_length; + int i; image_length = 0; TIFFGetField(s->tiff.tiff_file, TIFFTAG_IMAGELENGTH, &image_length); @@ -394,6 +407,13 @@ static int read_tiff_image(t4_state_t *s) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Read error at row %d.\n", s->file, row); break; } + if (s->tiff.photo_metric != PHOTOMETRIC_MINISWHITE) + { + for (i = 0; i < s->bytes_per_row; i++) + s->row_buf[i] = ~s->row_buf[i]; + } + if (s->tiff.fill_order != FILLORDER_LSB2MSB) + bit_reverse(s->row_buf, s->row_buf, s->bytes_per_row); if (encode_row(s)) return -1; }