[Freeswitch-svn] [commit] r9493 - in freeswitch/trunk/libs/spandsp: spandsp spandsp-sim/spandsp src src/spandsp tests

Freeswitch SVN anthm at freeswitch.org
Tue Sep 9 13:04:42 EDT 2008


Author: anthm
Date: Tue Sep  9 13:04:42 2008
New Revision: 9493

Added:
   freeswitch/trunk/libs/spandsp/src/spandsp/complex_vector_int.h
Modified:
   freeswitch/trunk/libs/spandsp/spandsp-sim/spandsp/g1050.h
   freeswitch/trunk/libs/spandsp/spandsp-sim/spandsp/rfc2198_sim.h
   freeswitch/trunk/libs/spandsp/spandsp/global-tones.xml
   freeswitch/trunk/libs/spandsp/spandsp/tones.dtd
   freeswitch/trunk/libs/spandsp/spandsp/tsb85.xml
   freeswitch/trunk/libs/spandsp/src/Makefile.am
   freeswitch/trunk/libs/spandsp/src/adsi.c
   freeswitch/trunk/libs/spandsp/src/async.c
   freeswitch/trunk/libs/spandsp/src/bert.c
   freeswitch/trunk/libs/spandsp/src/dds_int.c
   freeswitch/trunk/libs/spandsp/src/fsk.c
   freeswitch/trunk/libs/spandsp/src/gsm0610_lpc.c
   freeswitch/trunk/libs/spandsp/src/hdlc.c
   freeswitch/trunk/libs/spandsp/src/libspandsp.dsp
   freeswitch/trunk/libs/spandsp/src/modem_connect_tones.c
   freeswitch/trunk/libs/spandsp/src/queue.c
   freeswitch/trunk/libs/spandsp/src/silence_gen.c
   freeswitch/trunk/libs/spandsp/src/spandsp.h.in
   freeswitch/trunk/libs/spandsp/src/spandsp/async.h
   freeswitch/trunk/libs/spandsp/src/spandsp/complex.h
   freeswitch/trunk/libs/spandsp/src/spandsp/dds.h
   freeswitch/trunk/libs/spandsp/src/spandsp/echo.h
   freeswitch/trunk/libs/spandsp/src/spandsp/fsk.h
   freeswitch/trunk/libs/spandsp/src/spandsp/queue.h
   freeswitch/trunk/libs/spandsp/src/spandsp/t30.h
   freeswitch/trunk/libs/spandsp/src/spandsp/t38_core.h
   freeswitch/trunk/libs/spandsp/src/spandsp/t38_gateway.h
   freeswitch/trunk/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h
   freeswitch/trunk/libs/spandsp/src/spandsp/v17rx.h
   freeswitch/trunk/libs/spandsp/src/spandsp/v27ter_rx.h
   freeswitch/trunk/libs/spandsp/src/spandsp/v29rx.h
   freeswitch/trunk/libs/spandsp/src/spandsp/v8.h
   freeswitch/trunk/libs/spandsp/src/spandsp/vector_float.h
   freeswitch/trunk/libs/spandsp/src/spandsp/vector_int.h
   freeswitch/trunk/libs/spandsp/src/spandsp/version.h
   freeswitch/trunk/libs/spandsp/src/t30.c
   freeswitch/trunk/libs/spandsp/src/t31.c
   freeswitch/trunk/libs/spandsp/src/t38_gateway.c
   freeswitch/trunk/libs/spandsp/src/t38_non_ecm_buffer.c
   freeswitch/trunk/libs/spandsp/src/t38_terminal.c
   freeswitch/trunk/libs/spandsp/src/t4.c
   freeswitch/trunk/libs/spandsp/src/v17rx.c
   freeswitch/trunk/libs/spandsp/src/v17tx.c
   freeswitch/trunk/libs/spandsp/src/v22bis_rx.c
   freeswitch/trunk/libs/spandsp/src/v22bis_tx.c
   freeswitch/trunk/libs/spandsp/src/v27ter_rx.c
   freeswitch/trunk/libs/spandsp/src/v27ter_tx.c
   freeswitch/trunk/libs/spandsp/src/v29rx.c
   freeswitch/trunk/libs/spandsp/src/v29tx.c
   freeswitch/trunk/libs/spandsp/src/v29tx_constellation_maps.h
   freeswitch/trunk/libs/spandsp/src/v42.c
   freeswitch/trunk/libs/spandsp/src/v8.c
   freeswitch/trunk/libs/spandsp/src/vector_int.c
   freeswitch/trunk/libs/spandsp/tests/Makefile.am
   freeswitch/trunk/libs/spandsp/tests/bert_tests.c
   freeswitch/trunk/libs/spandsp/tests/echo_monitor.cpp
   freeswitch/trunk/libs/spandsp/tests/echo_tests.c
   freeswitch/trunk/libs/spandsp/tests/fax_decode.c
   freeswitch/trunk/libs/spandsp/tests/fax_tester.c
   freeswitch/trunk/libs/spandsp/tests/fax_tests.c
   freeswitch/trunk/libs/spandsp/tests/fsk_tests.c
   freeswitch/trunk/libs/spandsp/tests/g168_tests.c
   freeswitch/trunk/libs/spandsp/tests/hdlc_tests.c
   freeswitch/trunk/libs/spandsp/tests/line_model_monitor.cpp
   freeswitch/trunk/libs/spandsp/tests/media_monitor.cpp
   freeswitch/trunk/libs/spandsp/tests/modem_monitor.cpp
   freeswitch/trunk/libs/spandsp/tests/modem_monitor.h
   freeswitch/trunk/libs/spandsp/tests/oki_adpcm_tests.c
   freeswitch/trunk/libs/spandsp/tests/regression_tests.sh
   freeswitch/trunk/libs/spandsp/tests/super_tone_rx_tests.c
   freeswitch/trunk/libs/spandsp/tests/t38_non_ecm_buffer_tests.c
   freeswitch/trunk/libs/spandsp/tests/t4_tests.c
   freeswitch/trunk/libs/spandsp/tests/tsb85_tests.c
   freeswitch/trunk/libs/spandsp/tests/tsb85_tests.sh
   freeswitch/trunk/libs/spandsp/tests/v17_tests.c
   freeswitch/trunk/libs/spandsp/tests/v22bis_tests.c
   freeswitch/trunk/libs/spandsp/tests/v27ter_tests.c
   freeswitch/trunk/libs/spandsp/tests/v29_tests.c

Log:
update spandsp to use newest snapshot http://www.soft-switch.org/downloads/snapshots/spandsp/spandsp-20080910.tar.gz

Modified: freeswitch/trunk/libs/spandsp/spandsp-sim/spandsp/g1050.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/spandsp-sim/spandsp/g1050.h	(original)
+++ freeswitch/trunk/libs/spandsp/spandsp-sim/spandsp/g1050.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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 */

Modified: freeswitch/trunk/libs/spandsp/spandsp-sim/spandsp/rfc2198_sim.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/spandsp-sim/spandsp/rfc2198_sim.h	(original)
+++ freeswitch/trunk/libs/spandsp/spandsp-sim/spandsp/rfc2198_sim.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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 */

Modified: freeswitch/trunk/libs/spandsp/spandsp/global-tones.xml
==============================================================================
--- freeswitch/trunk/libs/spandsp/spandsp/global-tones.xml	(original)
+++ freeswitch/trunk/libs/spandsp/spandsp/global-tones.xml	Tue Sep  9 13:04:42 2008
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<!DOCTYPE global-tones SYSTEM "../tones.dtd">
+<!DOCTYPE global-tones SYSTEM "./tones.dtd">
 <global-tones>
   <tone-set country="Albania" uncode="al">
     <dial-tone>

Modified: freeswitch/trunk/libs/spandsp/spandsp/tones.dtd
==============================================================================
--- freeswitch/trunk/libs/spandsp/spandsp/tones.dtd	(original)
+++ freeswitch/trunk/libs/spandsp/spandsp/tones.dtd	Tue Sep  9 13:04:42 2008
@@ -35,6 +35,7 @@
 <!ELEMENT call-waiting-tone (step)* >
 <!ATTLIST call-waiting-tone
   domain    CDATA   #IMPLIED
+  type      CDATA   #IMPLIED
   >
 <!ELEMENT pay-tone (step)* >
 <!ATTLIST pay-tone
@@ -190,4 +191,5 @@
   level                 CDATA   #IMPLIED
   length                CDATA   #IMPLIED
   recorded-announcement CDATA   #IMPLIED
+  recognition-length    CDATA   #IMPLIED
   >

Modified: freeswitch/trunk/libs/spandsp/spandsp/tsb85.xml
==============================================================================
--- freeswitch/trunk/libs/spandsp/spandsp/tsb85.xml	(original)
+++ freeswitch/trunk/libs/spandsp/spandsp/tsb85.xml	Tue Sep  9 13:04:42 2008
@@ -1,6 +1,7 @@
 <?xml version="1.0"?>
+<!DOCTYPE fax-tests SYSTEM "./fax-tests.dtd">
 <fax-tests>
-<!-- $Id: tsb85.xml,v 1.15 2008/08/05 16:01:13 steveu Exp $ -->
+<!-- $Id: tsb85.xml,v 1.18 2008/09/09 15:30:43 steveu Exp $ -->
 <messages>
     <!-- TCF = 2700 bytes at 14400, 2250 at 12000, 1800 at 9600, 1350 at 7200, 900 at 4800 or 450 at 2400 -->
     <!-- Bad TCF == 10101010.... -->
@@ -963,6 +964,7 @@
         <step dir="T" type="POSTAMBLE"/>
     </test>
     <test name="MRGN17">
+        <!-- Tester called DUT, and sends 2 WHITE pages -->
         <step type="CALL"/>
 
         <!--<step dir="T" type="CNG"/>-->
@@ -2508,6 +2510,7 @@
         <step dir="T" type="POSTAMBLE"/>
     </test>
     <test name="MRGX10">
+        <!-- Tester calls DUT -->
         <step type="CALL"/>
 
         <step dir="R" type="CED"/>
@@ -2550,6 +2553,7 @@
         <step dir="T" type="POSTAMBLE"/>
     </test>
     <test name="MRGX11">
+        <!-- Tester calls DUT -->
         <step type="CALL"/>
 
         <step dir="R" type="CED"/>
@@ -2589,6 +2593,7 @@
         <step dir="T" type="POSTAMBLE"/>
     </test>
     <test name="MRGX12">
+        <!-- Tester calls DUT -->
         <step type="CALL"/>
 
         <step dir="R" type="CED"/>
@@ -2634,6 +2639,7 @@
         <step dir="T" type="POSTAMBLE"/>
     </test>
     <test name="MRGX13">
+        <!-- Tester calls DUT -->
         <step type="CALL"/>
 
         <step dir="R" type="CED"/>
@@ -2668,6 +2674,7 @@
         <step dir="T" type="POSTAMBLE"/>
     </test>
     <test name="MRGX14">
+        <!-- Tester calls DUT -->
         <step type="CALL"/>
 
         <step dir="R" type="CED"/>
@@ -2701,6 +2708,7 @@
         <step dir="T" type="POSTAMBLE"/>
     </test>
     <test name="MRGX15">
+        <!-- Tester calls DUT, and sends 1 WHITE page -->
         <step type="CALL"/>
 
         <step dir="R" type="CED"/>
@@ -2734,7 +2742,9 @@
 </test-group>
 <test-group name="Annex E - Polling receive test procedures">
     <test name="MTGP01">
+        <!-- DUT is set up for polling reception. DUT calls tester. -->
         <step type="ANSWER"/>
+        <step dir="T" type="SET" tag="RXFILE"/>
 
         <step dir="R" type="CNG"/>
 
@@ -2744,11 +2754,14 @@
         <step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 40 10"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
         <step dir="R" type="SILENCE"/>
     </test>
     <test name="MTGP02">
+        <!-- DUT is set up for polling reception. DUT calls tester. Tester sends 2 WHITE pages. -->
         <step type="ANSWER"/>
+        <step dir="T" type="SET" tag="RXFILE"/>
+        <step dir="T" type="SET" tag="IDENT" value="+0123456789"/>
 
         <step dir="R" type="CNG"/>
 
@@ -2758,7 +2771,8 @@
         <step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 80 10"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="CIG" fif="30 31 32 33 34 35 36 37 38 39 2B 20 20 20 20 20 20 20 20 20"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="NSC" value="FF C0 84 ..."/>
+        <step dir="R" type="HDLC" modem="V.21" tag="CIG" value="FF C0 82 9C 1C EC 6C AC 2C CC 4C 8C 0C D4 04 04 04 04 04 04 04 04 04"/>
         <step dir="R" type="HDLC" modem="V.21" tag="DTC" value="FF C8 81 ..."/>
         <step dir="R" type="SILENCE"/>
 
@@ -2767,19 +2781,19 @@
         <step dir="T" type="HDLC" tag="DCS" value="FF C8 41 00 00 00"/>
         <step dir="T" type="POSTAMBLE"/>
         <step type="WAIT" value="75"/>
-        <step dir="T" type="TCF" modem="V.27ter/4800" value="900"/>
+        <step dir="T" type="TCF" modem="V.27ter/2400" value="900"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="CFR" value="FF C8 21"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="CFR+" value="FF C8 A1"/>
         <step dir="R" type="SILENCE"/>
 
         <step type="WAIT" value="75"/>
-        <step dir="T" type="MSG" modem="V.27ter/4800" value="a4-white.tif"/>
+        <step dir="T" type="MSG" modem="V.27ter/2400" value="a4-white.tif"/>
         <step type="WAIT" value="75"/>
         <step dir="T" type="PREAMBLE" modem="V.21"/>
         <step dir="T" type="HDLC" tag="MPS" value="FF C8 72"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="MCF+" value="FF C8 B1"/>
         <step dir="R" type="SILENCE"/>
 
         <step type="WAIT" value="75"/>
@@ -2789,7 +2803,7 @@
         <step dir="T" type="HDLC" tag="EOP" value="FF C8 74"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="MCF+" value="FF C8 B1"/>
         <step dir="R" type="SILENCE"/>
 
         <step type="WAIT" value="75"/>
@@ -2798,7 +2812,11 @@
         <step dir="T" type="POSTAMBLE"/>
     </test>
     <test name="OTGP03">
+        <!-- DUT is set up for polling reception using a correct password. DUT calls tester. Tester sends 2 WHITE pages. -->
         <step type="ANSWER"/>
+        <step dir="T" type="SET" tag="RXFILE"/>
+        <step dir="T" type="SET" tag="IDENT" value="+0123456789"/>
+        <step dir="T" type="SET" tag="PWD" value="+9876543210"/>
 
         <step dir="R" type="CNG"/>
 
@@ -2847,7 +2865,9 @@
 </test-group>
 <test-group name="Annex F - Transmit test procedures">
     <test name="MTGN01">
-        <step type="ANSWER"/>
+        <!-- DUT calls tester and sends 1 IMPRESS and 1 WHITE page. DUT should send CNG and TSI. -->
+        <step type="ANSWER" value="a4-impress-white.tif"/>
+        <step dir="T" type="SET" tag="IDENT" value="+0123456789"/>
 
         <step dir="R" type="CNG"/>
 
@@ -2857,8 +2877,8 @@
         <step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 50 00"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" tag="TSI" value="FF C8 42 ..."/>
-        <step dir="R" type="HDLC" modem="V.21" tag="DCS" value="FF C8 41 ..."/>
+        <step dir="R" type="HDLC" modem="V.21" tag="TSI+" value="FF C0 C2 ..."/>
+        <step dir="R" type="HDLC" tag="DCS+" value="FF C8 C1 ..."/>
         <step dir="R" type="TCF" modem="V.27ter/4800" timeout="60000"/>
 
         <step type="WAIT" value="75"/>
@@ -2895,8 +2915,8 @@
         <step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 50 00"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" tag="TSI" value="FF C8 42 ..."/>
-        <step dir="R" type="HDLC" modem="V.21" tag="DCS" value="FF C8 41 00 50 00"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="TSI" value="FF C0 42 ..."/>
+        <step dir="R" type="HDLC" tag="DCS" value="FF C8 41 00 50 00"/>
         <step dir="R" type="TCF" modem="V.27ter/4800" timeout="60000"/>
 
         <step type="WAIT" value="75"/>
@@ -5222,7 +5242,10 @@
         <step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F"/>
     </test>
     <test name="MTGX17">
-        <step type="ANSWER"/>
+        <!-- DUT calls tester, and is configured to send 1 WHITE page. Tester responds with an unknown frame instead of
+             the first and second DIS. This is because some DUTs ignore the first frame coming after CED, and wait for
+             the second one to continue the call. -->
+        <step type="ANSWER" value="a4-white.tif"/>
 
         <step dir="R" type="CNG"/>
 
@@ -5255,7 +5278,8 @@
         <step dir="T" type="POSTAMBLE"/>
     </test>
     <test name="MTGX18">
-        <step type="ANSWER"/>
+        <!-- DUT calls tester, and sends 1 WHITE page -->
+        <step type="ANSWER" value="a4-white.tif"/>
 
         <step dir="R" type="CNG"/>
 
@@ -5278,7 +5302,7 @@
         </step>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCS" value="FF C8 41 00 50 00"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="DCS+" value="FF C8 C1 00 50 00"/>
         <step dir="R" type="TCF" modem="V.27ter/4800" timeout="60000"/>
 
         <step type="WAIT" value="75"/>
@@ -5287,17 +5311,18 @@
         <step dir="T" type="POSTAMBLE"/>
 
         <step dir="R" type="MSG" modem="V.27ter/4800" timeout="60000"/>
-        <step dir="R" type="HDLC" modem="V.21" tag="EOP" value="FF C8 74"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="EOP+" value="FF C8 F4"/>
 
         <step type="WAIT" value="75"/>
         <step dir="T" type="PREAMBLE" modem="V.21"/>
         <step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
     </test>
     <test name="MTGX19">
-        <step type="ANSWER"/>
+        <!-- DUT calls tester, and sends 1 WHITE page -->
+        <step type="ANSWER" value="a4-white.tif"/>
 
         <step dir="R" type="CNG"/>
 
@@ -5311,7 +5336,7 @@
         <step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 50 00"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCS" value="FF C8 41 00 50 00">
+        <step dir="R" type="HDLC" modem="V.21" tag="DCS+" value="FF C8 C1 00 50 00">
             <check name="MTGX19M01" desc="Unknown frame for command received"/>
         </step>
         <step dir="R" type="TCF" modem="V.27ter/4800" timeout="60000"/>
@@ -5322,17 +5347,18 @@
         <step dir="T" type="POSTAMBLE"/>
 
         <step dir="R" type="MSG" modem="V.27ter/4800"  timeout="60000"/>
-        <step dir="R" type="HDLC" modem="V.21" tag="EOP" value="FF C8 74"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="EOP+" value="FF C8 F4"/>
 
         <step type="WAIT" value="75"/>
         <step dir="T" type="PREAMBLE" modem="V.21"/>
         <step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
     </test>
     <test name="MTGX20">
-        <step type="ANSWER"/>
+        <!-- DUT calls tester, and attempts to send 1 WHITE page -->
+        <step type="ANSWER" value="a4-white.tif"/>
 
         <step dir="R" type="CNG"/>
  
@@ -5342,7 +5368,7 @@
         <step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 50 00"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCS" value="FF C8 41 00 50 00"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="DCS+" value="FF C8 C1 00 50 00"/>
         <step dir="R" type="TCF" modem="V.27ter/4800" timeout="60000"/>
 
         <step type="WAIT" value="75"/>
@@ -5351,7 +5377,7 @@
         <step dir="T" type="POSTAMBLE"/>
 
         <step dir="R" type="MSG" modem="V.27ter/4800" timeout="60000"/>
-        <step dir="R" type="HDLC" modem="V.21" tag="EOP" value="FF C8 74"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="EOP+" value="FF C8 F4"/>
 
         <step type="WAIT" value="75"/>
         <!-- UNKNOWN_BCS_2 -->
@@ -5359,12 +5385,13 @@
         <step dir="T" type="HDLC" tag="GARBAGE" value="FF C8 00"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F">
+        <step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF">
             <check name="MTGX20M01" desc="Unknown frame for response received"/>
         </step>
     </test>
     <test name="MTGX21">
-        <step type="ANSWER"/>
+        <!-- DUT calls tester, and sends 2 WHITE pages -->
+        <step type="ANSWER" value="a4-white-2p.tif"/>
 
         <step dir="R" type="CNG"/>
 
@@ -5374,7 +5401,7 @@
         <step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 50 00"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCS" value="FF C8 41 00 50 00"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="DCS+" value="FF C8 C1 00 50 00"/>
         <step dir="R" type="TCF" modem="V.27ter/4800" timeout="60000"/>
 
         <step type="WAIT" value="75"/>
@@ -5383,14 +5410,14 @@
         <step dir="T" type="POSTAMBLE"/>
 
         <step dir="R" type="MSG" modem="V.27ter/4800" timeout="60000"/>
-        <step dir="R" type="HDLC" modem="V.21" tag="MPS" value="FF C8 72"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="MPS+" value="FF C8 F2"/>
 
         <step type="WAIT" value="75"/>
         <!-- UNKNOWN_BCS_3 -->
         <step dir="T" type="PREAMBLE" modem="V.21" value="37"/>
         <step dir="T" type="HDLC" tag="GARBAGE" value="A2 02 B5 C9 7E 67"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="MPS" value="FF C8 72">
+        <step dir="R" type="HDLC" modem="V.21" tag="MPS+" value="FF C8 F2">
             <check name="MTGX21M01" desc="Unknown frame for response received"/>
         </step>
 
@@ -5400,17 +5427,18 @@
         <step dir="T" type="POSTAMBLE"/>
 
         <step dir="R" type="MSG" modem="V.27ter/4800"  timeout="60000"/>
-        <step dir="R" type="HDLC" modem="V.21" tag="EOP" value="FF C8 74"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="EOP+" value="FF C8 F4"/>
 
         <step type="WAIT" value="75"/>
         <step dir="T" type="PREAMBLE" modem="V.21"/>
         <step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
     </test>
     <test name="MTGX22">
-        <step type="ANSWER" value="a4-white.tif"/>
+        <!-- DUT calls tester, and sends 2 WHITE pages -->
+        <step type="ANSWER" value="a4-white-2p.tif"/>
 
         <step dir="R" type="CNG"/>
 
@@ -5429,13 +5457,13 @@
         <step dir="T" type="POSTAMBLE"/>
 
         <step dir="R" type="MSG" modem="V.27ter/4800" timeout="60000"/>
-        <step dir="R" type="HDLC" modem="V.21" tag="MPS" value="FF C8 72"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="MPS+" value="FF C8 F2"/>
 
         <step type="WAIT" value="75"/>
         <!-- UNKNOWN_BCS_4 -->
         <step dir="T" type="PREAMBLE" modem="V.21" value="43"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="MPS" value="FF C8 72">
+        <step dir="R" type="HDLC" modem="V.21" tag="MPS+" value="FF C8 F2">
             <check name="MTGX22M01" desc="Unknown frame for response received"/>
         </step>
 
@@ -5445,23 +5473,24 @@
         <step dir="T" type="POSTAMBLE"/>
 
         <step dir="R" type="MSG" modem="V.27ter/4800" timeout="60000"/>
-        <step dir="R" type="HDLC" modem="V.21" tag="EOP" value="FF C8 74"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="EOP+" value="FF C8 F4"/>
 
         <step type="WAIT" value="75"/>
         <step dir="T" type="PREAMBLE" modem="V.21"/>
         <step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
     </test>
     <test name="MTGX23">
+        <!-- DUT calls tester, and sends 1 WHITE page -->
         <step type="ANSWER" value="a4-white.tif"/>
 
         <step dir="R" type="CNG"/>
 
         <step dir="T" type="CED"/>
         <step type="WAIT" value="75"/>
-        <!-- CALLED-CAP-GROUP -->
+        <!-- CALLED-CAP-GROUP (TSB85 6.5.2.2) -->
         <step dir="T" type="PREAMBLE" modem="V.21" value="43"/>
         <step dir="T" type="HDLC" tag="NSF" value="FF C0 04 B5 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"/>
         <step dir="T" type="POSTAMBLE"/>
@@ -5481,19 +5510,22 @@
         <step dir="T" type="POSTAMBLE"/>
 
         <step dir="R" type="MSG" modem="V.27ter/4800" timeout="60000"/>
-        <step dir="R" type="HDLC" modem="V.21" tag="EOP+" value="FF C8 74"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="EOP+" value="FF C8 F4"/>
 
         <step type="WAIT" value="75"/>
         <step dir="T" type="PREAMBLE" modem="V.21"/>
         <step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
     </test>
 </test-group>
 <test-group name="Annex J - Polling transmit test procedures">
     <test name="MRGP01">
-        <step type="CALL"/>
+        <!-- DUT has been prepared with 2 WHITE pages, which are available for polling without a password. Tester calls DUT.
+             DUT should send TSI for this test procedure. -->
+        <step type="CALL" value="a4-white-2p.tif"/>
+        <step dir="T" type="SET" tag="IDENT" value="1234567890"/>
 
         <!--<step dir="T" type="CNG"/>-->
 
@@ -5508,18 +5540,18 @@
         <step dir="T" type="HDLC" tag="DTC" value="FF C8 81 00 50 10"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" tag="TSI" value="FF C8 42 ...">
+        <step dir="R" type="HDLC" modem="V.21" tag="TSI" value="FF C0 42 ...">
             <check name="MRGP01M04" desc="Polled, TSI prescence"/>
             <check name="MRGP01M05" desc="Polled, TSI framing"/>
             <check name="MRGP01M06" desc="Polled, TSI FIF content"/>
         </step>
-        <step dir="R" type="HDLC" modem="V.21" tag="DCS" value="FF C8 41 00 50 00">
+        <step dir="R" type="HDLC" tag="DCS" value="FF C8 41 00 50 10">
             <check name="MRGP01M02" desc="Polled, trasnmit DCS"/>
             <check name="MRGP01M03" desc="Polled, DCS preamble"/>
             <check name="MRGP01M07" desc="Polled, DCS framing"/>
             <check name="MRGP01M08" desc="Polled, DCS FIF content"/>
         </step>
-        <step dir="R" type="TCF">
+        <step dir="R" type="TCF" modem="V.27ter/4800">
             <check name="MRGP01M09" desc="Polled, DCS TCF"/>
         </step>
         <step dir="R" type="SILENCE"/>
@@ -5568,7 +5600,10 @@
         <step dir="R" type="SILENCE"/>
     </test>
     <test name="MRGP02">
-        <step type="CALL" value="a4-white.tif"/>
+        <!-- DUT has been prepared with 2 WHITE pages, which are available for polling using a password. Tester calls DUT -->
+        <step type="CALL" value="a4-white-2p.tif"/>
+        <step dir="T" type="SET" tag="IDENT" value="1234567890"/>
+        <step dir="R" type="SET" tag="PWD" value="+9876543210"/>
 
         <!--<step dir="T" type="CNG"/>-->
 
@@ -5584,7 +5619,7 @@
         <step dir="T" type="HDLC" tag="DTC" value="FF C8 81 00 50 11 01 01 01 40"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="TSI" value="FF C8 42 ..."/>
+        <step dir="R" type="HDLC" modem="V.21" tag="TSI" value="FF C0 42 ..."/>
         <step dir="R" type="HDLC" tag="DCS" value="FF C8 41 ...">
             <check name="MRGP02M02" desc="Polled, DUT accepts tester's password"/>
         </step>
@@ -5619,7 +5654,9 @@
         <step dir="R" type="SILENCE"/>
     </test>
     <test name="MRGP03">
+        <!-- DUT has been prepared with 2 WHITE pages, which are available for polling using a password. Tester calls DUT -->
         <step type="CALL"/>
+        <step dir="R" type="SET" tag="PWD" value="+0123456789"/>
 
         <!--<step dir="T" type="CNG"/>-->
 
@@ -5639,7 +5676,9 @@
         <step dir="R" type="SILENCE"/>
     </test>
     <test name="MRGP04">
-        <step type="CALL"/>
+        <!-- DUT has been prepared with 2 WHITE pages, which are available for polling using a password. Tester calls DUT -->
+        <step type="CALL" value="a4-white-2p.tif"/>
+        <step dir="R" type="SET" tag="PWD" value="+0123456789"/>
 
         <!--<step dir="T" type="CNG"/>-->
 
@@ -5658,6 +5697,7 @@
         <step dir="R" type="SILENCE"/>
     </test>
     <test name="MRGP05">
+        <!-- DUT has no document available for polling. Tester calls DUT -->
         <step type="CALL"/>
 
         <!--<step dir="T" type="CNG"/>-->
@@ -5679,7 +5719,8 @@
         <step dir="R" type="SILENCE"/>
     </test>
     <test name="MRGP06">
-        <step type="CALL" value="a4-white.tif"/>
+        <!-- DUT has been prepared with 2 WHITE pages, which are available for polling without a password. Tester calls DUT -->
+        <step type="CALL" value="a4-white-2p.tif"/>
 
         <!--<step dir="T" type="CNG"/>-->
 
@@ -5704,7 +5745,7 @@
         <step dir="T" type="POSTAMBLE"/>
 
         <step dir="R" type="MSG" modem="V.27ter/4800" timeout="60000"/>
-        <step dir="R" type="HDLC" modem="V.21" tag="MPS" value="FF C8 72"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="MPS+" value="FF C8 F2"/>
         <step dir="R" type="SILENCE"/>
 
         <step type="WAIT" value="75"/>
@@ -5713,7 +5754,7 @@
         <step dir="T" type="POSTAMBLE"/>
 
         <step dir="R" type="MSG" modem="V.27ter/4800" timeout="60000"/>
-        <step dir="R" type="HDLC" modem="V.21" tag="EOP" value="FF C8 74"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="EOP+" value="FF C8 F4"/>
         <step dir="R" type="SILENCE"/>
 
         <step type="WAIT" value="75"/>
@@ -5721,11 +5762,13 @@
         <step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F"/>
+        <step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
         <step dir="R" type="SILENCE"/>
     </test>
     <test name="MRGP07">
-        <step type="CALL"/>
+        <!-- DUT has been prepared with 2 WHITE pages, which are available for polling using a password. Tester calls DUT -->
+        <step type="CALL" value="a4-white-2p.tif"/>
+        <step dir="R" type="SET" tag="PWD" value="+9876543210"/>
 
         <!--<step dir="T" type="CNG"/>-->
 
@@ -5738,12 +5781,13 @@
         <step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 50 00"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F">
+        <step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF">
             <check name="MRGP07M01" desc="Polled, DUT rejects DIS in place of DTC for lackof password"/>
         </step>
         <step dir="R" type="SILENCE"/>
     </test>
     <test name="MRGP08">
+        <!-- DUT has no document available for polling. Tester calls DUT -->
         <step type="CALL"/>
 
         <!--<step dir="T" type="CNG"/>-->
@@ -5757,12 +5801,14 @@
         <step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 50 00"/>
         <step dir="T" type="POSTAMBLE"/>
 
-        <step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F">
+        <step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF">
             <check name="MRGP08M01" desc="Polled, DUT rejects DIS in place of DTC for no document available"/>
         </step>
         <step dir="R" type="SILENCE"/>
     </test>
     <test name="ORGP09">
+        <!-- DUT has been prepared with 1 WHITE page, which is available for polling without password. Tester calls DUT
+             Tester sends 1 WHITE page -->
         <step type="CALL" value="a4-white.tif"/>
 
         <!--<step dir="T" type="CNG"/>-->
@@ -5821,6 +5867,8 @@
         <step dir="R" type="SILENCE"/>
     </test>
     <test name="ORGP10">
+        <!-- DUT has been prepared with 1 WHITE page, which is available for polling without password. Tester calls DUT
+             Tester sends 1 WHITE page -->
         <step type="CALL" value="a4-white.tif"/>
 
         <!--<step dir="T" type="CNG"/>-->

Modified: freeswitch/trunk/libs/spandsp/src/Makefile.am
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/Makefile.am	(original)
+++ freeswitch/trunk/libs/spandsp/src/Makefile.am	Tue Sep  9 13:04:42 2008
@@ -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 @@
                          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 \

Modified: freeswitch/trunk/libs/spandsp/src/adsi.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/adsi.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/adsi.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     }
     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 @@
         /* 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 @@
             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 @@
     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 */

Modified: freeswitch/trunk/libs/spandsp/src/async.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/async.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/async.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
         /* 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 @@
         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
         {

Modified: freeswitch/trunk/libs/spandsp/src/bert.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/bert.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/bert.c	Tue Sep  9 13:04:42 2008
@@ -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 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 @@
     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;

Modified: freeswitch/trunk/libs/spandsp/src/dds_int.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/dds_int.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/dds_int.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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 ------------------------------------------------------------*/

Modified: freeswitch/trunk/libs/spandsp/src/fsk.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/fsk.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/fsk.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
         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 @@
                 {
                     /* 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 @@
             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

Modified: freeswitch/trunk/libs/spandsp/src/gsm0610_lpc.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/gsm0610_lpc.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/gsm0610_lpc.c	Tue Sep  9 13:04:42 2008
@@ -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 <math.h>
 #endif
 #include <stdlib.h>
+#include <memory.h>
 
 #include "spandsp/telephony.h"
 #include "spandsp/bitstream.h"

Modified: freeswitch/trunk/libs/spandsp/src/hdlc.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/hdlc.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/hdlc.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     /* 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 @@
         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 @@
         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 @@
         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 @@
     {
         /* 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 @@
                 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 @@
     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 @@
 
     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;
     }

Modified: freeswitch/trunk/libs/spandsp/src/libspandsp.dsp
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/libspandsp.dsp	(original)
+++ freeswitch/trunk/libs/spandsp/src/libspandsp.dsp	Tue Sep  9 13:04:42 2008
@@ -459,6 +459,10 @@
 # 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

Modified: freeswitch/trunk/libs/spandsp/src/modem_connect_tones.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/modem_connect_tones.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/modem_connect_tones.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
         /* 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;

Modified: freeswitch/trunk/libs/spandsp/src/queue.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/queue.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/queue.c	Tue Sep  9 13:04:42 2008
@@ -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 <inttypes.h>
 #include <sys/types.h>
 
+#define FULLY_DEFINE_QUEUE_STATE_T
 #include "spandsp/queue.h"
 
 int queue_empty(queue_state_t *s)

Modified: freeswitch/trunk/libs/spandsp/src/silence_gen.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/silence_gen.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/silence_gen.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
         {
             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;
     }

Modified: freeswitch/trunk/libs/spandsp/src/spandsp.h.in
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp.h.in	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp.h.in	Tue Sep  9 13:04:42 2008
@@ -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 <spandsp/vector_float.h>
 #include <spandsp/complex_vector_float.h>
 #include <spandsp/vector_int.h>
+#include <spandsp/complex_vector_int.h>
 #include <spandsp/arctan2.h>
 #include <spandsp/biquad.h>
 #include <spandsp/fir.h>

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/async.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/async.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/async.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
 #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 @@
 {
 #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 @@
     \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)

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/complex.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/complex.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/complex.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
 /*- 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 @@
 /*- 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 @@
 }
 /*- 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;

Added: freeswitch/trunk/libs/spandsp/src/spandsp/complex_vector_int.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/complex_vector_int.h	Tue Sep  9 13:04:42 2008
@@ -0,0 +1,104 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * complex_vector_int.h
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/dds.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/dds.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/dds.h	Tue Sep  9 13:04:42 2008
@@ -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_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,20 +113,69 @@
 */
 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.
+/*! \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.
+    \param scale The scaling factor.
+    \param phase The phase offset.
     \return The complex signal amplitude, between (-32767, -32767) and (32767, 32767).
 */
-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 integer tone sample, with modulation.
+/*! \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).
 */
-complexi_t dds_complexi_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase);
+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.

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/echo.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/echo.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/echo.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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
 };
 
 /*!

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/fsk.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/fsk.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/fsk.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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[];

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/queue.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/queue.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/queue.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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)

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/t30.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/t30.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/t30.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
     T30_SUPPORT_V29 = 0x02,
     T30_SUPPORT_V17 = 0x04,
     T30_SUPPORT_V34 = 0x08,
-    T30_SUPPORT_IAF = 0x10,
+    T30_SUPPORT_IAF = 0x10
 };
 
 enum

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/t38_core.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/t38_core.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/t38_core.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
 {
     T38_FIELD_CLASS_NONE = 0,
     T38_FIELD_CLASS_HDLC,
-    T38_FIELD_CLASS_NON_ECM,
+    T38_FIELD_CLASS_NON_ECM
 };
 
 /*! T.38 message types */

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/t38_gateway.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/t38_gateway.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/t38_gateway.h	Tue Sep  9 13:04:42 2008
@@ -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 */
@@ -126,6 +126,21 @@
 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. */
     int len[T38_TX_HDLC_BUFS];
@@ -133,6 +148,7 @@
     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. */

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
 
     /*! \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 @@
     \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 @@
     \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_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_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging);
+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.

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/v17rx.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/v17rx.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/v17rx.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
     /*! \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 @@
     /*! 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 @@
     /*! 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;

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/v27ter_rx.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/v27ter_rx.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/v27ter_rx.h	Tue Sep  9 13:04:42 2008
@@ -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,28 +144,39 @@
     /*! \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 Current 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;
-#if defined(SPANDSP_USE_FIXED_POINTx)
     /*! \brief The adaptive equalizer coefficients. */
-    complexi_t eq_coeff[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
+    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. */
-    complexi_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
+    complexi16_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];
+    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 Current 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 Integration variable for damping the Gardner algorithm tests. */
     int gardner_integrate;
@@ -174,8 +185,6 @@
     /*! \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];

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/v29rx.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/v29rx.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/v29rx.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
     /*! \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 @@
 
     /*! \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 @@
     /*! 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 @@
     \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.

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/v8.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/v8.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/v8.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/vector_float.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/vector_float.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/vector_float.h	Tue Sep  9 13:04:42 2008
@@ -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_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
 

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/vector_int.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/vector_int.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/vector_int.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
 {
 #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.

Modified: freeswitch/trunk/libs/spandsp/src/spandsp/version.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/spandsp/version.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/spandsp/version.h	Tue Sep  9 13:04:42 2008
@@ -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 ------------------------------------------------------------*/

Modified: freeswitch/trunk/libs/spandsp/src/t30.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/t30.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/t30.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     }
     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 @@
             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 @@
     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 @@
         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 @@
         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 @@
         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 @@
     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 @@
             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 @@
             }
         }
         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 @@
             }
         }
         break;
-    case PUTBIT_ABORT:
+    case SIG_STATUS_ABORT:
         /* Just ignore these */
         break;
     default:
@@ -5559,10 +5557,10 @@
         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 @@
         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,

Modified: freeswitch/trunk/libs/spandsp/src/t31.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/t31.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/t31.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
                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 @@
             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 @@
            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 @@
     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 @@
                 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 @@
     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 @@
         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 @@
             }
         }
         break;
-    case PUTBIT_ABORT:
+    case SIG_STATUS_ABORT:
         /* Just ignore these */
         break;
     default:

Modified: freeswitch/trunk/libs/spandsp/src/t38_gateway.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/t38_gateway.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/t38_gateway.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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 @@
 
     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 @@
     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 @@
         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 @@
             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 @@
             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 @@
             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 @@
     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 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 @@
     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 @@
     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 @@
     
     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_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 @@
     {
     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 @@
         /* 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 @@
             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 @@
            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)
+            {
+                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
             {
-                s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (data_type | FLAG_DATA);
-                pump_out_final_hdlc(s, FALSE);
+                /* 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 @@
            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))
+            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))
+            {
                 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  &&  (s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] & HDLC_FLAG_MISSING_DATA) == 0)
+            if (data_type == T38_DATA_V21)
             {
-                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]);
+                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*/
-            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;
+            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 @@
         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 @@
            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))
+            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))
+            {
                 queue_missing_indicator(s, data_type);
+                hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
+            }
             /*endif*/
-            if (s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] > 0)
+            /* 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);
+                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 @@
         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 @@
            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 @@
             {
                 /* 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 @@
         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 @@
             {
                 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 @@
             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 @@
     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 @@
     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 @@
         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);

Modified: freeswitch/trunk/libs/spandsp/src/t38_non_ecm_buffer.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/t38_non_ecm_buffer.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/t38_non_ecm_buffer.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
             {
                 /* 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 @@
                              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 @@
 }
 /*- 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));

Modified: freeswitch/trunk/libs/spandsp/src/t38_terminal.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/t38_terminal.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/t38_terminal.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
             &&
             (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 @@
         {
             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 @@
         {
             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 @@
     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 @@
             {
                 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);

Modified: freeswitch/trunk/libs/spandsp/src/t4.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/t4.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/t4.c	Tue Sep  9 13:04:42 2008
@@ -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 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 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;
 }

Modified: freeswitch/trunk/libs/spandsp/src/v17rx.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/v17rx.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/v17rx.c	Tue Sep  9 13:04:42 2008
@@ -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,6 +471,40 @@
 }
 /*- End of function --------------------------------------------------------*/
 
+static __inline__ void symbol_sync(v17_rx_state_t *s)
+{
+    int i;
+    float v;
+    float p;
+
+    /* This routine adapts the position of the half baud samples entering the equalizer. */
+
+    /* 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 HF noise */
+    s->baud_phase -= p;
+
+    if (fabsf(s->baud_phase) > 100.0f)
+    {
+        if (s->baud_phase > 0.0f)
+            i = (s->baud_phase > 1000.0f)  ?  15  :  1;
+        else
+            i = (s->baud_phase < -1000.0f)  ?  -15  :  -1;
+        //printf("v = %10.5f %5d - %f %f %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction);
+
+        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] =
@@ -484,10 +518,11 @@
     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 v;
     float p;
     int bit;
     int i;
@@ -496,8 +531,7 @@
     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 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. */
@@ -509,29 +543,7 @@
         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 HF noise */
-    s->baud_phase -= p;
-
-    if (fabsf(s->baud_phase) > 100.0f)
-    {
-        if (s->baud_phase > 0.0f)
-            i = (s->baud_phase > 1000.0f)  ?  15  :  1;
-        else
-            i = (s->baud_phase < -1000.0f)  ?  -15  :  -1;
-        //printf("v = %10.5f %5d - %f %f %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);
 
@@ -545,7 +557,7 @@
         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 @@
         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 @@
         }
         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 @@
                 /* 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 @@
             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 @@
             /* 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 @@
                 /* 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 @@
                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 @@
             {
                 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 @@
             {
                 /* 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 @@
                 /* 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 @@
     default:
         /* We failed to train! */
         /* Park here until the carrier drops. */
-        target = &z;
+        target = &zero;
         break;
     }
     if (s->qam_report)
@@ -979,7 +991,7 @@
                     /* 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 @@
 #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 @@
             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);
     }

Modified: freeswitch/trunk/libs/spandsp/src/v17tx.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/v17tx.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/v17tx.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
             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;

Modified: freeswitch/trunk/libs/spandsp/src/v22bis_rx.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/v22bis_rx.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/v22bis_rx.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
             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 @@
             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)
         {

Modified: freeswitch/trunk/libs/spandsp/src/v22bis_tx.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/v22bis_tx.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/v22bis_tx.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
 {
     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. */

Modified: freeswitch/trunk/libs/spandsp/src/v27ter_rx.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/v27ter_rx.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/v27ter_rx.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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 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_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 @@
 }
 /*- 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 @@
 }
 /*- 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 @@
 }
 /*- 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 @@
 }
 /*- 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 @@
 }
 /*- 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 @@
         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 @@
                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 @@
                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 @@
             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 @@
             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 @@
     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 @@
             {
                 /* 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 @@
                 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 @@
     }
     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,11 +760,16 @@
     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;
 
     if (s->bit_rate == 4800)
@@ -664,7 +822,7 @@
                         /* 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 @@
 #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 @@
                 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 @@
                         /* 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 @@
 #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 @@
                 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 @@
     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 @@
     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 @@
     s->gardner_integrate = 0;
     s->total_baud_timing_correction = 0;
     s->gardner_step = 512;
-    s->baud_phase = 0;
+    s->baud_half = 0;
 
     return 0;
 }

Modified: freeswitch/trunk/libs/spandsp/src/v27ter_tx.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/v27ter_tx.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/v27ter_tx.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
 {
     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 @@
         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. */

Modified: freeswitch/trunk/libs/spandsp/src/v29rx.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/v29rx.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/v29rx.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
 };
 
 /* 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 @@
 }
 /*- 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 @@
 }
 /*- 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 @@
 {
     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 @@
 }
 /*- 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 @@
 }
 /*- 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 @@
        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 @@
 }
 /*- 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 @@
     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);
-        raw_bits = phase_steps_9600[(nearest - s->constellation_state) & 7];
-        for (i = 0;  i < 3;  i++)
+        if (s->bit_rate == 9600)
         {
-            put_bit(s, raw_bits);
-            raw_bits >>= 1;
+            /* 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;
         }
-        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 @@
 }
 /*- 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 @@
         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 @@
     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 @@
         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 @@
         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 @@
                 ||
                 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 @@
                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 @@
         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 @@
             {
                 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 @@
         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 @@
                 /* 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 @@
     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 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 @@
                     /* 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 @@
 #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 @@
         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 @@
         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 @@
             step = -s->eq_put_step;
             if (step > RX_PULSESHAPER_COEFF_SETS - 1)
                 step = RX_PULSESHAPER_COEFF_SETS - 1;
+            s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2);
 #if defined(SPANDSP_USE_FIXED_POINT)
-            zi.im = (int32_t) rx_pulseshaper[step][0].im*(int32_t) s->rrc_filter[s->rrc_filter_step];
+            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++)
-                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;
+                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
-            zz.im = rx_pulseshaper[step][0].im*s->rrc_filter[s->rrc_filter_step];
+            v = 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. */
+                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 @@
     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 @@
     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 @@
     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 @@
     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;

Modified: freeswitch/trunk/libs/spandsp/src/v29tx.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/v29tx.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/v29tx.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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 @@
         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.

Modified: freeswitch/trunk/libs/spandsp/src/v29tx_constellation_maps.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/v29tx_constellation_maps.h	(original)
+++ freeswitch/trunk/libs/spandsp/src/v29tx_constellation_maps.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
     {-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 @@
     { 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] =

Modified: freeswitch/trunk/libs/spandsp/src/v42.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/v42.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/v42.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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 @@
     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*/

Modified: freeswitch/trunk/libs/spandsp/src/v8.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/v8.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/v8.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
         /* 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;

Modified: freeswitch/trunk/libs/spandsp/src/vector_int.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/src/vector_int.c	(original)
+++ freeswitch/trunk/libs/spandsp/src/vector_int.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
 
         " .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 @@
 
         " .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 @@
 
         " .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 @@
         " 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"

Modified: freeswitch/trunk/libs/spandsp/tests/Makefile.am
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/Makefile.am	(original)
+++ freeswitch/trunk/libs/spandsp/tests/Makefile.am	Tue Sep  9 13:04:42 2008
@@ -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_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

Modified: freeswitch/trunk/libs/spandsp/tests/bert_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/bert_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/bert_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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);

Modified: freeswitch/trunk/libs/spandsp/tests/echo_monitor.cpp
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/echo_monitor.cpp	(original)
+++ freeswitch/trunk/libs/spandsp/tests/echo_monitor.cpp	Tue Sep  9 13:04:42 2008
@@ -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;
-
-Fl_Audio_Meter *audio_meter;
-
-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_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 = NULL;
-double line_model_re_plot[512];
+struct line_model_monitor_s
+{
+    Fl_Double_Window *w;
 
-static int skip = 0;
+    Fl_Audio_Meter *audio_meter;
+    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_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;
+    double line_model_re_plot[512];
 
-int in_ptr;
+    int in_ptr;
 #if defined(HAVE_FFTW3_H)
-double in[1024][2];
-double out[1024][2];
+    double in[1024][2];
+    double out[1024][2];
 #else
-fftw_complex in[1024];
-fftw_complex out[1024];
+    fftw_complex in[1024];
+    fftw_complex out[1024];
 #endif
-fftw_plan p;
+    fftw_plan p;
+};
+
+
+static int skip = 0;
+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 @@
     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 @@
     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 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 @@
         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 @@
         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 @@
     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);
-
-    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);
-
-    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);
-
-    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);
-
-    spec_amp->current();
-
-    c_spec->end();
-
-    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();
-
-    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);
-
-    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();
-
-    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();
-
-    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();
-
-    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);
-
-    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();
-
-    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();
-
-    c_line_model->end();
-
-    audio_meter = new Fl_Audio_Meter(810, 40, 10, 250, "");
-    audio_meter->box(FL_PLASTIC_UP_BOX);
-    audio_meter->type(FL_VERT_AUDIO_METER);
-
-    c_right->end();
-
-    Fl_Group::current()->resizable(c_right);
-    w->end();
-    w->show();
+    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);
+
+    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);
+
+    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);
+
+    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);
+
+    s->spec_amp->current();
+    s->spec_re = NULL;
+
+    s->c_spec->end();
+
+    s->c_right = new Fl_Group(440, 0, 465, 405);
+
+    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();
+
+    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);
+
+    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();
+
+    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();
+
+    s->c_can->end();
+    s->can_re = NULL;
+
+    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();
+
+    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);
+
+    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();
+
+    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->c_line_model->end();
+    s->line_model_re = NULL;
+
+    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);
+
+    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;

Modified: freeswitch/trunk/libs/spandsp/tests/echo_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/echo_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/echo_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
 }
 /*- End of function --------------------------------------------------------*/
 
+#if 0
 static void level_measurement_device_reset(level_measurement_device_t *dev)
 {
     int i;
@@ -279,6 +280,7 @@
     return 0;
 }
 /*- End of function --------------------------------------------------------*/
+#endif
 
 static float level_measurement_device_get_peak(level_measurement_device_t *dev)
 {
@@ -534,6 +536,7 @@
 }
 /*- End of function --------------------------------------------------------*/
 
+#if 0
 static int16_t local_hoth_noise_signal(void)
 {
     static float hoth_noise = 0.0;
@@ -542,6 +545,7 @@
     return (int16_t) hoth_noise;
 }
 /*- End of function --------------------------------------------------------*/
+#endif
 
 static int16_t far_hoth_noise_signal(void)
 {
@@ -1483,7 +1487,7 @@
 }
 /*- 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;

Modified: freeswitch/trunk/libs/spandsp/tests/fax_decode.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/fax_decode.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/fax_decode.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
         /* 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 @@
         /* 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 @@
         /* 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 @@
         /* 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 @@
         /* 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;

Modified: freeswitch/trunk/libs/spandsp/tests/fax_tester.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/fax_tester.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/fax_tester.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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 @@
         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 @@
     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 @@
         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 @@
     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 --------------------------------------------------------*/

Modified: freeswitch/trunk/libs/spandsp/tests/fax_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/fax_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/fax_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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)))

Modified: freeswitch/trunk/libs/spandsp/tests/fsk_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/fsk_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/fsk_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
 
 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 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;
 }

Modified: freeswitch/trunk/libs/spandsp/tests/g168_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/g168_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/g168_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
 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 @@
 }
 /*- 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 @@
     return handle;
 }
 /*- End of function --------------------------------------------------------*/
+#endif
 
 static void signal_load(signal_source_t *sig, const char *name)
 {
@@ -367,6 +369,8 @@
     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 --------------------------------------------------------*/

Modified: freeswitch/trunk/libs/spandsp/tests/hdlc_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/hdlc_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/hdlc_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <unistd.h>
 #include <string.h>
 
 #include "spandsp.h"
@@ -92,43 +93,15 @@
     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 @@
 /*- End of function --------------------------------------------------------*/
 #endif
 
-int main(int argc, char *argv[])
+static void hdlc_tests(void)
 {
     printf("HDLC module tests\n");
 
@@ -811,6 +784,76 @@
     }
 #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 --------------------------------------------------------*/

Modified: freeswitch/trunk/libs/spandsp/tests/line_model_monitor.cpp
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/line_model_monitor.cpp	(original)
+++ freeswitch/trunk/libs/spandsp/tests/line_model_monitor.cpp	Tue Sep  9 13:04:42 2008
@@ -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;
-
-Fl_Audio_Meter *audio_meter;
+struct line_model_monitor_s
+{
+    Fl_Double_Window *w;
 
-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_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 = NULL;
-double line_model_re_plot[512];
+    Fl_Audio_Meter *audio_meter;
 
-static int skip = 0;
+    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_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;
+    double line_model_re_plot[512];
 
-int in_ptr;
+    int in_ptr;
 #if defined(HAVE_FFTW3_H)
-double in[1024][2];
-double out[1024][2];
+    double in[1024][2];
+    double out[1024][2];
 #else
-fftw_complex in[1024];
-fftw_complex out[1024];
+    fftw_complex in[1024];
+    fftw_complex out[1024];
 #endif
-fftw_plan p;
+    fftw_plan p;
+};
+
+static int skip = 0;
+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 @@
     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 @@
     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 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 @@
         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 @@
         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 @@
     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);
-
-    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);
-
-    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);
-
-    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);
-
-    spec_amp->current();
-
-    c_spec->end();
-
-    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();
-
-    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);
-
-    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();
-
-    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();
-
-    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();
-
-    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);
-
-    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();
-
-    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();
-
-    c_line_model->end();
-
-    audio_meter = new Fl_Audio_Meter(810, 40, 10, 250, "");
-    audio_meter->box(FL_PLASTIC_UP_BOX);
-    audio_meter->type(FL_VERT_AUDIO_METER);
-
-    c_right->end();
-
-    Fl_Group::current()->resizable(c_right);
-    w->end();
-    w->show();
+    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);
+
+    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);
+
+    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);
+
+    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);
+
+    s->spec_amp->current();
+    s->spec_re = NULL;
+
+    s->c_spec->end();
+
+    s->c_right = new Fl_Group(440, 0, 465, 405);
+
+    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();
+
+    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);
+
+    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();
+
+    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();
+
+    s->c_can->end();
+
+    s->can_re = NULL;
+
+    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();
+
+    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);
+
+    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();
+
+    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;
+
+    s->c_line_model->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);
+
+    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;

Modified: freeswitch/trunk/libs/spandsp/tests/media_monitor.cpp
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/media_monitor.cpp	(original)
+++ freeswitch/trunk/libs/spandsp/tests/media_monitor.cpp	Tue Sep  9 13:04:42 2008
@@ -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;
-
-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_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;
+    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;
+    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;
+    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 @@
     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 @@
     
     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();
-
-    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);
-
-    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();
-
-    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();
-
-    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();
-
-    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);
-
-    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();
-
-    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->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();
+
+    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);
+
+    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();
+
+    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();
+
+    s->c_sent->end();
+
+    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();
+
+    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);
+
+    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();
+
+    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;
     
-    for (i = 0;  i < 500;  i++)
-        sent_re_plot[2*i] = i;
-    sent_re_plot_min = 99999.0;
-    sent_re_plot_max = 0.0;
-
-    c_received->end();
+    s->received_delays = NULL;
+    s->highest_seq_no_seen = -1;
 
-    c_right->end();
-
-    Fl_Group::current()->resizable(c_right);
-    w->end();
-    w->show();
-
-    in_ptr = 0;
+    for (i = 0;  i < 500;  i++)
+        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;
+
+    s->c_received->end();
+
+    s->c_right->end();
+
+    Fl_Group::current()->resizable(s->c_right);
+    s->w->end();
+    s->w->show();
 
     Fl::check();
     return 0;

Modified: freeswitch/trunk/libs/spandsp/tests/modem_monitor.cpp
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/modem_monitor.cpp	(original)
+++ freeswitch/trunk/libs/spandsp/tests/modem_monitor.cpp	Tue Sep  9 13:04:42 2008
@@ -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 @@
             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 @@
 }
 /*- 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;

Modified: freeswitch/trunk/libs/spandsp/tests/modem_monitor.h
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/modem_monitor.h	(original)
+++ freeswitch/trunk/libs/spandsp/tests/modem_monitor.h	Tue Sep  9 13:04:42 2008
@@ -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 @@
 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);

Modified: freeswitch/trunk/libs/spandsp/tests/oki_adpcm_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/oki_adpcm_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/oki_adpcm_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 outframes;
     int oki_bytes;
     int bit_rate;
-    float x;
     double pre_energy;
     double post_energy;
     double diff_energy;

Modified: freeswitch/trunk/libs/spandsp/tests/regression_tests.sh
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/regression_tests.sh	(original)
+++ freeswitch/trunk/libs/spandsp/tests/regression_tests.sh	Tue Sep  9 13:04:42 2008
@@ -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 @@
 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=$?

Modified: freeswitch/trunk/libs/spandsp/tests/super_tone_rx_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/super_tone_rx_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/super_tone_rx_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     xmlDocPtr doc;
     xmlNsPtr ns;
     xmlNodePtr cur;
-#if 0
+#if 1
     xmlValidCtxt valid;
 #endif
     xmlChar *x;
@@ -272,15 +272,14 @@
     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");

Modified: freeswitch/trunk/libs/spandsp/tests/t38_non_ecm_buffer_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/t38_non_ecm_buffer_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/t38_non_ecm_buffer_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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 @@
     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 @@
     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 @@
     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;

Modified: freeswitch/trunk/libs/spandsp/tests/t4_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/t4_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/t4_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
         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 @@
                 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 @@
             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. */

Modified: freeswitch/trunk/libs/spandsp/tests/tsb85_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/tsb85_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/tsb85_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 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 @@
     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 @@
     }
     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 @@
     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 @@
     }
     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 @@
                 ||
                 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 @@
     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 @@
         {
             /* 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 @@
                 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 @@
             }
         }
 
-        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 @@
 
     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 @@
             exit(2);
         }
         /*endif*/
-        afFreeFileSetup(filesetup);
     }
     /*endif*/
 }
@@ -1014,22 +1147,21 @@
     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 @@
         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);

Modified: freeswitch/trunk/libs/spandsp/tests/tsb85_tests.sh
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/tsb85_tests.sh	(original)
+++ freeswitch/trunk/libs/spandsp/tests/tsb85_tests.sh	Tue Sep  9 13:04:42 2008
@@ -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 @@
 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 @@
 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
 
 #for TEST in MTGX17 MTGX18 MTGX19 MTGX20 MTGX21 MTGX22 MTGX23 ; do
-#    run_tsb85_test
-#done
+for TEST in 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 MRGP01 MRGP02 MRGP03 MRGP04 MRGP05 MRGP06 MRGP07 MRGP08 ; do
     run_tsb85_test
 done
 
-#for TEST in ORGP09 ORGP10 ; do
-#    run_tsb85_test
-#done
+for TEST in ORGP09 ORGP10 ; do
+    run_tsb85_test
+done

Modified: freeswitch/trunk/libs/spandsp/tests/v17_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/v17_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/v17_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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 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 @@
 
                 /* 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 @@
     {
         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)

Modified: freeswitch/trunk/libs/spandsp/tests/v22bis_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/v22bis_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/v22bis_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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;
     }

Modified: freeswitch/trunk/libs/spandsp/tests/v27ter_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/v27ter_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/v27ter_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 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 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 @@
 
                 /* 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 @@
             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)
         {

Modified: freeswitch/trunk/libs/spandsp/tests/v29_tests.c
==============================================================================
--- freeswitch/trunk/libs/spandsp/tests/v29_tests.c	(original)
+++ freeswitch/trunk/libs/spandsp/tests/v29_tests.c	Tue Sep  9 13:04:42 2008
@@ -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 @@
     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 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 @@
 {
     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 @@
         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++)
@@ -257,6 +256,7 @@
             if (use_gui)
                 qam_monitor_update_equalizer(qam_monitor, coeffs, len);
 #endif
+#endif
             update_interval = 100;
         }
     }
@@ -451,8 +451,8 @@
 
                 /* 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 @@
             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)



More information about the Freeswitch-svn mailing list