mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-15 08:29:45 +00:00
update spandsp to use newest snapshot http://www.soft-switch.org/downloads/snapshots/spandsp/spandsp-20080910.tar.gz
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9493 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
bc5cf34915
commit
ea964d8fe6
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: g1050.h,v 1.7 2008/04/17 18:03:23 steveu Exp $
|
||||
* $Id: g1050.h,v 1.8 2008/09/09 16:13:12 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -243,7 +243,7 @@ typedef struct g1050_queue_element_s
|
||||
double departure_time;
|
||||
double arrival_time;
|
||||
int len;
|
||||
uint8_t pkt[0];
|
||||
uint8_t pkt[];
|
||||
} g1050_queue_element_t;
|
||||
|
||||
/*! The model definition for a complete end-to-end path */
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: rfc2198_sim.h,v 1.3 2008/04/17 18:03:23 steveu Exp $
|
||||
* $Id: rfc2198_sim.h,v 1.4 2008/09/09 16:13:12 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -43,7 +43,7 @@ typedef struct rfc2198_sim_queue_element_s
|
||||
double departure_time;
|
||||
double arrival_time;
|
||||
int len;
|
||||
uint8_t pkt[0];
|
||||
uint8_t pkt[];
|
||||
} rfc2198_sim_queue_element_t;
|
||||
|
||||
/*! The model definition for a complete end-to-end path */
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
>
|
||||
|
@ -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"/>-->
|
||||
|
@ -16,7 +16,7 @@
|
||||
## License along with this program; if not, write to the Free Software
|
||||
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
##
|
||||
## $Id: Makefile.am,v 1.100 2008/08/14 14:06:05 steveu Exp $
|
||||
## $Id: Makefile.am,v 1.101 2008/09/08 12:45:02 steveu Exp $
|
||||
|
||||
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
|
||||
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
|
||||
@ -120,6 +120,7 @@ nobase_include_HEADERS = spandsp/adsi.h \
|
||||
spandsp/complex.h \
|
||||
spandsp/complex_filters.h \
|
||||
spandsp/complex_vector_float.h \
|
||||
spandsp/complex_vector_int.h \
|
||||
spandsp/dc_restore.h \
|
||||
spandsp/dds.h \
|
||||
spandsp/dtmf.h \
|
||||
|
@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: adsi.c,v 1.59 2008/07/02 14:48:25 steveu Exp $
|
||||
* $Id: adsi.c,v 1.60 2008/09/07 12:45:16 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -134,7 +134,7 @@ static int adsi_tx_get_bit(void *user_data)
|
||||
}
|
||||
else
|
||||
{
|
||||
bit = PUTBIT_END_OF_DATA;
|
||||
bit = SIG_STATUS_END_OF_DATA;
|
||||
if (s->tx_signal_on)
|
||||
{
|
||||
/* The FSK should now be switched off. */
|
||||
@ -176,7 +176,7 @@ static void adsi_rx_put_bit(void *user_data, int bit)
|
||||
/* Special conditions */
|
||||
switch (bit)
|
||||
{
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Carrier up.\n");
|
||||
s->consecutive_ones = 0;
|
||||
s->bit_pos = 0;
|
||||
@ -184,7 +184,7 @@ static void adsi_rx_put_bit(void *user_data, int bit)
|
||||
s->msg_len = 0;
|
||||
s->baudot_shift = 0;
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Carrier down.\n");
|
||||
break;
|
||||
default:
|
||||
@ -297,18 +297,17 @@ static void adsi_tdd_put_async_byte(void *user_data, int byte)
|
||||
if (byte < 0)
|
||||
{
|
||||
/* Special conditions */
|
||||
printf("Status is %s (%d)\n", signal_status_to_str(byte), byte);
|
||||
switch (byte)
|
||||
{
|
||||
case PUTBIT_CARRIER_UP:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Carrier up.\n");
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
s->consecutive_ones = 0;
|
||||
s->bit_pos = 0;
|
||||
s->in_progress = 0;
|
||||
s->msg_len = 0;
|
||||
s->baudot_shift = 0;
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Carrier down.\n");
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
if (s->msg_len > 0)
|
||||
{
|
||||
/* Whatever we have to date constitutes the message */
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: async.c,v 1.11 2008/05/13 13:17:21 steveu Exp $
|
||||
* $Id: async.c,v 1.13 2008/09/07 12:45:16 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -39,6 +39,37 @@
|
||||
#include "spandsp/telephony.h"
|
||||
#include "spandsp/async.h"
|
||||
|
||||
const char *signal_status_to_str(int status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
return "Carrier down";
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
return "Carrier up";
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
return "Training in progress";
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
return "Training succeeded";
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
return "Training failed";
|
||||
case SIG_STATUS_FRAMING_OK:
|
||||
return "Framing OK";
|
||||
case SIG_STATUS_END_OF_DATA:
|
||||
return "End of data";
|
||||
case SIG_STATUS_ABORT:
|
||||
return "Abort";
|
||||
case SIG_STATUS_BREAK:
|
||||
return "Break";
|
||||
case SIG_STATUS_SHUTDOWN_COMPLETE:
|
||||
return "Shutdown complete";
|
||||
case SIG_STATUS_OCTET_REPORT:
|
||||
return "Octet report";
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
async_rx_state_t *async_rx_init(async_rx_state_t *s,
|
||||
int data_bits,
|
||||
int parity,
|
||||
@ -80,12 +111,12 @@ void async_rx_put_bit(void *user_data, int bit)
|
||||
/* Special conditions */
|
||||
switch (bit)
|
||||
{
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
case PUTBIT_END_OF_DATA:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
case SIG_STATUS_END_OF_DATA:
|
||||
s->put_byte(s->user_data, bit);
|
||||
s->bitpos = 0;
|
||||
s->byte_in_progress = 0;
|
||||
@ -194,7 +225,7 @@ int async_tx_get_bit(void *user_data)
|
||||
if ((s->byte_in_progress = s->get_byte(s->user_data)) < 0)
|
||||
{
|
||||
/* No more data */
|
||||
bit = PUTBIT_END_OF_DATA;
|
||||
bit = SIG_STATUS_END_OF_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: bert.c,v 1.27 2008/05/13 13:17:22 steveu Exp $
|
||||
* $Id: bert.c,v 1.28 2008/09/07 12:45:16 steveu Exp $
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
@ -78,7 +78,7 @@ int bert_get_bit(bert_state_t *s)
|
||||
int bit;
|
||||
|
||||
if (s->limit && s->tx_bits >= s->limit)
|
||||
return PUTBIT_END_OF_DATA;
|
||||
return SIG_STATUS_END_OF_DATA;
|
||||
bit = 0;
|
||||
switch (s->pattern_class)
|
||||
{
|
||||
@ -185,27 +185,7 @@ void bert_put_bit(bert_state_t *s, int bit)
|
||||
if (bit < 0)
|
||||
{
|
||||
/* Special conditions */
|
||||
switch (bit)
|
||||
{
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training in progress\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training succeeded\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Carrier down\n");
|
||||
break;
|
||||
default:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Eh!\n");
|
||||
break;
|
||||
}
|
||||
printf("Status is %s (%d)\n", signal_status_to_str(bit), bit);
|
||||
return;
|
||||
}
|
||||
bit = (bit & 1) ^ s->invert;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: dds_int.c,v 1.9 2008/07/02 14:48:25 steveu Exp $
|
||||
* $Id: dds_int.c,v 1.10 2008/09/01 16:07:33 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -288,4 +288,58 @@ complexi_t dds_complexi_mod(uint32_t *phase_acc, int32_t phase_rate, int scale,
|
||||
return amp;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
complexi16_t dds_lookup_complexi16(uint32_t phase)
|
||||
{
|
||||
return complex_seti16(dds_lookup(phase + (1 << 30)), dds_lookup(phase));
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
complexi16_t dds_complexi16(uint32_t *phase_acc, int32_t phase_rate)
|
||||
{
|
||||
complexi16_t amp;
|
||||
|
||||
amp = complex_seti16(dds_lookup(*phase_acc + (1 << 30)), dds_lookup(*phase_acc));
|
||||
*phase_acc += phase_rate;
|
||||
return amp;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
complexi16_t dds_complexi16_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase)
|
||||
{
|
||||
complexi16_t amp;
|
||||
|
||||
amp = complex_seti16((dds_lookup(*phase_acc + phase + (1 << 30))*scale) >> 15,
|
||||
(dds_lookup(*phase_acc + phase)*scale) >> 15);
|
||||
*phase_acc += phase_rate;
|
||||
return amp;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
complexi32_t dds_lookup_complexi32(uint32_t phase)
|
||||
{
|
||||
return complex_seti32(dds_lookup(phase + (1 << 30)), dds_lookup(phase));
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
complexi32_t dds_complexi32(uint32_t *phase_acc, int32_t phase_rate)
|
||||
{
|
||||
complexi32_t amp;
|
||||
|
||||
amp = complex_seti32(dds_lookup(*phase_acc + (1 << 30)), dds_lookup(*phase_acc));
|
||||
*phase_acc += phase_rate;
|
||||
return amp;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
complexi32_t dds_complexi32_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase)
|
||||
{
|
||||
complexi32_t amp;
|
||||
|
||||
amp = complex_seti32((dds_lookup(*phase_acc + phase + (1 << 30))*scale) >> 15,
|
||||
(dds_lookup(*phase_acc + phase)*scale) >> 15);
|
||||
*phase_acc += phase_rate;
|
||||
return amp;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fsk.c,v 1.44 2008/07/16 17:01:49 steveu Exp $
|
||||
* $Id: fsk.c,v 1.46 2008/09/07 12:45:16 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -163,12 +163,12 @@ int fsk_tx(fsk_tx_state_t *s, int16_t *amp, int len)
|
||||
if ((s->baud_frac += s->baud_inc) >= SAMPLE_RATE*100)
|
||||
{
|
||||
s->baud_frac -= SAMPLE_RATE*100;
|
||||
if ((bit = s->get_bit(s->get_bit_user_data)) == PUTBIT_END_OF_DATA)
|
||||
if ((bit = s->get_bit(s->get_bit_user_data)) == SIG_STATUS_END_OF_DATA)
|
||||
{
|
||||
if (s->status_handler)
|
||||
s->status_handler(s->status_user_data, MODEM_TX_STATUS_DATA_EXHAUSTED);
|
||||
s->status_handler(s->status_user_data, SIG_STATUS_END_OF_DATA);
|
||||
if (s->status_handler)
|
||||
s->status_handler(s->status_user_data, MODEM_TX_STATUS_SHUTDOWN_COMPLETE);
|
||||
s->status_handler(s->status_user_data, SIG_STATUS_SHUTDOWN_COMPLETE);
|
||||
s->shutdown = TRUE;
|
||||
break;
|
||||
}
|
||||
@ -329,7 +329,7 @@ int fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len)
|
||||
{
|
||||
/* Count down a short delay, to ensure we push the last
|
||||
few bits through the filters before stopping. */
|
||||
report_status_change(s, PUTBIT_CARRIER_DOWN);
|
||||
report_status_change(s, SIG_STATUS_CARRIER_DOWN);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -340,7 +340,7 @@ int fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len)
|
||||
if (power < s->carrier_on_power)
|
||||
continue;
|
||||
s->signal_present = 1;
|
||||
report_status_change(s, PUTBIT_CARRIER_UP);
|
||||
report_status_change(s, SIG_STATUS_CARRIER_UP);
|
||||
}
|
||||
/* Non-coherent FSK demodulation by correlation with the target tones
|
||||
over a one baud interval. The slow V.xx specs. are too open ended
|
||||
|
@ -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"
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: hdlc.c,v 1.60 2008/05/13 13:17:22 steveu Exp $
|
||||
* $Id: hdlc.c,v 1.61 2008/09/07 12:45:16 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -47,8 +47,8 @@ static void rx_special_condition(hdlc_rx_state_t *s, int condition)
|
||||
/* Special conditions */
|
||||
switch (condition)
|
||||
{
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
/* Reset the HDLC receiver. */
|
||||
s->raw_bit_stream = 0;
|
||||
s->len = 0;
|
||||
@ -56,10 +56,10 @@ static void rx_special_condition(hdlc_rx_state_t *s, int condition)
|
||||
s->flags_seen = 0;
|
||||
s->framing_ok_announced = FALSE;
|
||||
/* Fall through */
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case PUTBIT_END_OF_DATA:
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
case SIG_STATUS_END_OF_DATA:
|
||||
s->frame_handler(s->user_data, NULL, condition, TRUE);
|
||||
break;
|
||||
default:
|
||||
@ -81,7 +81,7 @@ static __inline__ void octet_set_and_count(hdlc_rx_state_t *s)
|
||||
if (--s->octet_count <= 0)
|
||||
{
|
||||
s->octet_count = s->octet_count_report_interval;
|
||||
s->frame_handler(s->user_data, NULL, PUTBIT_OCTET_REPORT, TRUE);
|
||||
s->frame_handler(s->user_data, NULL, SIG_STATUS_OCTET_REPORT, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -104,7 +104,7 @@ static __inline__ void octet_count(hdlc_rx_state_t *s)
|
||||
if (--s->octet_count <= 0)
|
||||
{
|
||||
s->octet_count = s->octet_count_report_interval;
|
||||
s->frame_handler(s->user_data, NULL, PUTBIT_OCTET_REPORT, TRUE);
|
||||
s->frame_handler(s->user_data, NULL, SIG_STATUS_OCTET_REPORT, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -116,7 +116,7 @@ static void rx_flag_or_abort(hdlc_rx_state_t *s)
|
||||
{
|
||||
/* Hit HDLC abort */
|
||||
s->rx_aborts++;
|
||||
s->frame_handler(s->user_data, NULL, PUTBIT_ABORT, TRUE);
|
||||
s->frame_handler(s->user_data, NULL, SIG_STATUS_ABORT, TRUE);
|
||||
/* If we have not yet seen enough flags, restart the count. If we
|
||||
are beyond that point, just back off one step, so we need to see
|
||||
another flag before proceeding to collect frame octets. */
|
||||
@ -184,7 +184,7 @@ static void rx_flag_or_abort(hdlc_rx_state_t *s)
|
||||
s->flags_seen = 0;
|
||||
if (++s->flags_seen >= s->framing_ok_threshold && !s->framing_ok_announced)
|
||||
{
|
||||
s->frame_handler(s->user_data, NULL, PUTBIT_FRAMING_OK, TRUE);
|
||||
s->frame_handler(s->user_data, NULL, SIG_STATUS_FRAMING_OK, TRUE);
|
||||
s->framing_ok_announced = TRUE;
|
||||
}
|
||||
}
|
||||
@ -493,7 +493,7 @@ int hdlc_tx_get_byte(hdlc_tx_state_t *s)
|
||||
if (s->tx_end)
|
||||
{
|
||||
s->tx_end = FALSE;
|
||||
return PUTBIT_END_OF_DATA;
|
||||
return SIG_STATUS_END_OF_DATA;
|
||||
}
|
||||
return s->idle_octet;
|
||||
}
|
||||
@ -522,7 +522,7 @@ int hdlc_tx_get(hdlc_tx_state_t *s, uint8_t buf[], size_t max_len)
|
||||
|
||||
for (i = 0; i < max_len; i++)
|
||||
{
|
||||
if ((x = hdlc_tx_get_byte(s)) == PUTBIT_END_OF_DATA)
|
||||
if ((x = hdlc_tx_get_byte(s)) == SIG_STATUS_END_OF_DATA)
|
||||
return i;
|
||||
buf[i] = x;
|
||||
}
|
||||
|
@ -459,6 +459,10 @@ SOURCE=.\spandsp/complex_vector_float.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\spandsp/complex_vector_int.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\spandsp/dc_restore.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: modem_connect_tones.c,v 1.27 2008/08/13 14:55:51 steveu Exp $
|
||||
* $Id: modem_connect_tones.c,v 1.28 2008/09/07 12:45:16 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -284,12 +284,12 @@ static void v21_put_bit(void *user_data, int bit)
|
||||
/* Special conditions. */
|
||||
switch (bit)
|
||||
{
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
/* Only declare tone off, if we were the one to declare tone on. */
|
||||
if (s->tone_present == MODEM_CONNECT_TONES_FAX_PREAMBLE)
|
||||
report_tone_state(s, MODEM_CONNECT_TONES_NONE, -99);
|
||||
/* Fall through */
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
s->raw_bit_stream = 0;
|
||||
s->num_bits = 0;
|
||||
s->flags_seen = 0;
|
||||
|
@ -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)
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: silence_gen.c,v 1.14 2008/07/26 04:53:00 steveu Exp $
|
||||
* $Id: silence_gen.c,v 1.16 2008/09/07 12:45:16 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -59,7 +59,7 @@ int silence_gen(silence_gen_state_t *s, int16_t *amp, int max_len)
|
||||
{
|
||||
max_len = s->remaining_samples;
|
||||
if (max_len && s->status_handler)
|
||||
s->status_handler(s->status_user_data, MODEM_TX_STATUS_SHUTDOWN_COMPLETE);
|
||||
s->status_handler(s->status_user_data, SIG_STATUS_SHUTDOWN_COMPLETE);
|
||||
}
|
||||
s->remaining_samples -= max_len;
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: async.h,v 1.16 2008/07/17 14:27:11 steveu Exp $
|
||||
* $Id: async.h,v 1.18 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -49,42 +49,36 @@ and decoding must occur before data is fed to this module.
|
||||
#if !defined(_SPANDSP_ASYNC_H_)
|
||||
#define _SPANDSP_ASYNC_H_
|
||||
|
||||
/*! Special "bit" values for the put and get bit functions */
|
||||
/*! Special "bit" values for the bitstream put and get functions, and the signal status functions. */
|
||||
enum
|
||||
{
|
||||
/*! \brief The carrier signal has dropped. */
|
||||
PUTBIT_CARRIER_DOWN = -1,
|
||||
SIG_STATUS_CARRIER_DOWN = -1,
|
||||
/*! \brief The carrier signal is up. This merely indicates that carrier
|
||||
energy has been seen. It is not an indication that the carrier is either
|
||||
valid, or of the expected type. */
|
||||
PUTBIT_CARRIER_UP = -2,
|
||||
SIG_STATUS_CARRIER_UP = -2,
|
||||
/*! \brief The modem is training. This is an early indication that the
|
||||
signal seems to be of the right type. This may be needed in time critical
|
||||
applications, like T.38, to forward an early indication of what is happening
|
||||
on the wire. */
|
||||
PUTBIT_TRAINING_IN_PROGRESS = -3,
|
||||
SIG_STATUS_TRAINING_IN_PROGRESS = -3,
|
||||
/*! \brief The modem has trained, and is ready for data exchange. */
|
||||
PUTBIT_TRAINING_SUCCEEDED = -4,
|
||||
SIG_STATUS_TRAINING_SUCCEEDED = -4,
|
||||
/*! \brief The modem has failed to train. */
|
||||
PUTBIT_TRAINING_FAILED = -5,
|
||||
SIG_STATUS_TRAINING_FAILED = -5,
|
||||
/*! \brief Packet framing (e.g. HDLC framing) is OK. */
|
||||
PUTBIT_FRAMING_OK = -6,
|
||||
SIG_STATUS_FRAMING_OK = -6,
|
||||
/*! \brief The data stream has ended. */
|
||||
PUTBIT_END_OF_DATA = -7,
|
||||
SIG_STATUS_END_OF_DATA = -7,
|
||||
/*! \brief An abort signal (e.g. an HDLC abort) has been received. */
|
||||
PUTBIT_ABORT = -8,
|
||||
SIG_STATUS_ABORT = -8,
|
||||
/*! \brief A break signal (e.g. an async break) has been received. */
|
||||
PUTBIT_BREAK = -9,
|
||||
SIG_STATUS_BREAK = -9,
|
||||
/*! \brief A modem has completed its task, and shut down. */
|
||||
SIG_STATUS_SHUTDOWN_COMPLETE = -10,
|
||||
/*! \brief Regular octet report for things like HDLC to the MTP standards. */
|
||||
PUTBIT_OCTET_REPORT = -10
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
/*! \brief The data source for a transmitter is exhausted. */
|
||||
MODEM_TX_STATUS_DATA_EXHAUSTED = -1,
|
||||
/*! \brief The transmitter has completed its task, and shut down. */
|
||||
MODEM_TX_STATUS_SHUTDOWN_COMPLETE = -2
|
||||
SIG_STATUS_OCTET_REPORT = -11
|
||||
};
|
||||
|
||||
/*! Message put function for data pumps */
|
||||
@ -185,6 +179,12 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*! Convert a signal status to a short text description.
|
||||
\brief Convert a signal status to a short text description.
|
||||
\param status The modem signal status.
|
||||
\return A pointer to the description. */
|
||||
const char *signal_status_to_str(int status);
|
||||
|
||||
/*! Initialise an asynchronous data transmit context.
|
||||
\brief Initialise an asynchronous data transmit context.
|
||||
\param s The transmitter context.
|
||||
@ -231,11 +231,11 @@ async_rx_state_t *async_rx_init(async_rx_state_t *s,
|
||||
\brief Accept a bit from a received serial bit stream
|
||||
\param user_data An opaque point which must point to a receiver context.
|
||||
\param bit The new bit. Some special values are supported for this field.
|
||||
- PUTBIT_CARRIER_UP
|
||||
- PUTBIT_CARRIER_DOWN
|
||||
- PUTBIT_TRAINING_SUCCEEDED
|
||||
- PUTBIT_TRAINING_FAILED
|
||||
- PUTBIT_END_OF_DATA */
|
||||
- SIG_STATUS_CARRIER_UP
|
||||
- SIG_STATUS_CARRIER_DOWN
|
||||
- SIG_STATUS_TRAINING_SUCCEEDED
|
||||
- SIG_STATUS_TRAINING_FAILED
|
||||
- SIG_STATUS_END_OF_DATA */
|
||||
void async_rx_put_bit(void *user_data, int bit);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: complex.h,v 1.16 2008/04/17 14:27:00 steveu Exp $
|
||||
* $Id: complex.h,v 1.18 2008/09/03 13:41:42 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -329,6 +329,56 @@ static __inline__ complexl_t complex_mull(const complexl_t *x, const complexl_t
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
static __inline__ complexi_t complex_muli(const complexi_t *x, const complexi_t *y)
|
||||
{
|
||||
complexi_t z;
|
||||
|
||||
z.re = x->re*y->re - x->im*y->im;
|
||||
z.im = x->re*y->im + x->im*y->re;
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ complexi16_t complex_muli16(const complexi16_t *x, const complexi16_t *y)
|
||||
{
|
||||
complexi16_t z;
|
||||
|
||||
z.re = (int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im;
|
||||
z.im = (int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re;
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ complexi16_t complex_mul_q1_15(const complexi16_t *x, const complexi16_t *y)
|
||||
{
|
||||
complexi16_t z;
|
||||
|
||||
z.re = ((int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im) >> 15;
|
||||
z.im = ((int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re) >> 15;
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ complexi32_t complex_muli32i16(const complexi32_t *x, const complexi16_t *y)
|
||||
{
|
||||
complexi32_t z;
|
||||
|
||||
z.re = x->re*(int32_t) y->re - x->im*(int32_t) y->im;
|
||||
z.im = x->re*(int32_t) y->im + x->im*(int32_t) y->re;
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ complexi32_t complex_muli32(const complexi32_t *x, const complexi32_t *y)
|
||||
{
|
||||
complexi32_t z;
|
||||
|
||||
z.re = x->re*y->re - x->im*y->im;
|
||||
z.im = x->re*y->im + x->im*y->re;
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ complexf_t complex_divf(const complexf_t *x, const complexf_t *y)
|
||||
{
|
||||
complexf_t z;
|
||||
@ -399,7 +449,7 @@ static __inline__ complexl_t complex_conjl(const complexl_t *x)
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
static __inline__ complexi_t complexi_conj(const complexi_t *x)
|
||||
static __inline__ complexi_t complex_conji(const complexi_t *x)
|
||||
{
|
||||
complexi_t z;
|
||||
|
||||
@ -409,6 +459,26 @@ static __inline__ complexi_t complexi_conj(const complexi_t *x)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ complexi16_t complex_conji16(const complexi16_t *x)
|
||||
{
|
||||
complexi16_t z;
|
||||
|
||||
z.re = x->re;
|
||||
z.im = -x->im;
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ complexi32_t complex_conji32(const complexi32_t *x)
|
||||
{
|
||||
complexi32_t z;
|
||||
|
||||
z.re = x->re;
|
||||
z.im = -x->im;
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ float powerf(const complexf_t *x)
|
||||
{
|
||||
return x->re*x->re + x->im*x->im;
|
||||
|
104
libs/spandsp/src/spandsp/complex_vector_int.h
Normal file
104
libs/spandsp/src/spandsp/complex_vector_int.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* complex_vector_int.h
|
||||
*
|
||||
* Written by Steve Underwood <steveu@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 ------------------------------------------------------------*/
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: dds.h,v 1.18 2008/04/17 14:27:00 steveu Exp $
|
||||
* $Id: dds.h,v 1.20 2008/09/04 14:40:05 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -100,6 +100,12 @@ int16_t dds_lookup(uint32_t phase);
|
||||
*/
|
||||
int16_t dds_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase);
|
||||
|
||||
/*! \brief Lookup the complex integer value of a specified phase.
|
||||
\param phase The phase accumulator value to be looked up.
|
||||
\return The complex signal amplitude, between (-32767, -32767) and (32767, 32767).
|
||||
*/
|
||||
complexi_t dds_lookup_complexi(uint32_t phase);
|
||||
|
||||
/*! \brief Generate a complex integer tone sample.
|
||||
\param phase_acc A pointer to a phase accumulator value.
|
||||
\param phase_rate The phase increment to be applied.
|
||||
@ -107,12 +113,6 @@ int16_t dds_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phas
|
||||
*/
|
||||
complexi_t dds_complexi(uint32_t *phase_acc, int32_t phase_rate);
|
||||
|
||||
/*! \brief Lookup the complex integer value of a specified phase.
|
||||
\param phase The phase accumulator value to be looked up.
|
||||
\return The complex signal amplitude, between (-32767, -32767) and (32767, 32767).
|
||||
*/
|
||||
complexi_t dds_lookup_complexi(uint32_t phase);
|
||||
|
||||
/*! \brief Generate a complex integer tone sample, with modulation.
|
||||
\param phase_acc A pointer to a phase accumulator value.
|
||||
\param phase_rate The phase increment to be applied.
|
||||
@ -122,6 +122,61 @@ complexi_t dds_lookup_complexi(uint32_t phase);
|
||||
*/
|
||||
complexi_t dds_complexi_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase);
|
||||
|
||||
/*! \brief Generate a complex 16 bit integer tone sample.
|
||||
\param phase_acc A pointer to a phase accumulator value.
|
||||
\param phase_rate The phase increment to be applied.
|
||||
\return The complex signal amplitude, between (-32767, -32767) and (32767, 32767).
|
||||
*/
|
||||
complexi16_t dds_lookup_complexi16(uint32_t phase);
|
||||
|
||||
/*! \brief Generate a complex 16 bit integer tone sample.
|
||||
\param phase_acc A pointer to a phase accumulator value.
|
||||
\param phase_rate The phase increment to be applied.
|
||||
\return The complex signal amplitude, between (-32767, -32767) and (32767, 32767).
|
||||
*/
|
||||
complexi16_t dds_complexi16(uint32_t *phase_acc, int32_t phase_rate);
|
||||
|
||||
/*! \brief Generate a complex 16bit integer tone sample, with modulation.
|
||||
\param phase_acc A pointer to a phase accumulator value.
|
||||
\param phase_rate The phase increment to be applied.
|
||||
\param scale The scaling factor.
|
||||
\param phase The phase offset.
|
||||
\return The complex signal amplitude, between (-32767, -32767) and (32767, 32767).
|
||||
*/
|
||||
complexi16_t dds_complexi16_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase);
|
||||
|
||||
/*! \brief Generate a complex 32 bit integer tone sample, with modulation.
|
||||
\param phase_acc A pointer to a phase accumulator value.
|
||||
\param phase_rate The phase increment to be applied.
|
||||
\param scale The scaling factor.
|
||||
\param phase The phase offset.
|
||||
\return The complex signal amplitude, between (-32767, -32767) and (32767, 32767).
|
||||
*/
|
||||
complexi32_t dds_complexi32_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase);
|
||||
|
||||
/*! \brief Generate a complex 32 bit integer tone sample.
|
||||
\param phase_acc A pointer to a phase accumulator value.
|
||||
\param phase_rate The phase increment to be applied.
|
||||
\return The complex signal amplitude, between (-32767, -32767) and (32767, 32767).
|
||||
*/
|
||||
complexi32_t dds_lookup_complexi32(uint32_t phase);
|
||||
|
||||
/*! \brief Generate a complex 32 bit integer tone sample.
|
||||
\param phase_acc A pointer to a phase accumulator value.
|
||||
\param phase_rate The phase increment to be applied.
|
||||
\return The complex signal amplitude, between (-32767, -32767) and (32767, 32767).
|
||||
*/
|
||||
complexi32_t dds_complexi32(uint32_t *phase_acc, int32_t phase_rate);
|
||||
|
||||
/*! \brief Generate a complex 32 bit integer tone sample, with modulation.
|
||||
\param phase_acc A pointer to a phase accumulator value.
|
||||
\param phase_rate The phase increment to be applied.
|
||||
\param scale The scaling factor.
|
||||
\param phase The phase offset.
|
||||
\return The complex signal amplitude, between (-32767, -32767) and (32767, 32767).
|
||||
*/
|
||||
complexi32_t dds_complexi32_mod(uint32_t *phase_acc, int32_t phase_rate, int scale, int32_t phase);
|
||||
|
||||
/*! \brief Find the phase rate equivalent to a frequency, in Hz.
|
||||
\param frequency The frequency, in Hz.
|
||||
\return The equivalent phase rate.
|
||||
|
@ -24,7 +24,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: echo.h,v 1.15 2008/08/29 10:02:47 steveu Exp $
|
||||
* $Id: echo.h,v 1.16 2008/09/04 14:40:05 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -126,7 +126,7 @@ enum
|
||||
ECHO_CAN_USE_SUPPRESSOR = 0x10,
|
||||
ECHO_CAN_USE_TX_HPF = 0x20,
|
||||
ECHO_CAN_USE_RX_HPF = 0x40,
|
||||
ECHO_CAN_DISABLE = 0x80,
|
||||
ECHO_CAN_DISABLE = 0x80
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fsk.h,v 1.30 2008/07/16 14:23:48 steveu Exp $
|
||||
* $Id: fsk.h,v 1.31 2008/09/04 14:40:05 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -111,7 +111,7 @@ enum
|
||||
FSK_BELL103CH1,
|
||||
FSK_BELL103CH2,
|
||||
FSK_BELL202,
|
||||
FSK_WEITBRECHT, /* Used for TDD (Telecom Device for the Deaf) */
|
||||
FSK_WEITBRECHT /* Used for TDD (Telecom Device for the Deaf) */
|
||||
};
|
||||
|
||||
extern const fsk_spec_t preset_fsk_specs[];
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: queue.h,v 1.16 2008/05/30 13:51:28 steveu Exp $
|
||||
* $Id: queue.h,v 1.17 2008/09/09 16:25:51 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -63,8 +63,10 @@ typedef struct
|
||||
volatile int iptr;
|
||||
/*! \brief The buffer output pointer. */
|
||||
volatile int optr;
|
||||
#if defined(FULLY_DEFINE_QUEUE_STATE_T)
|
||||
/*! \brief The data buffer, sized at the time the structure is created. */
|
||||
uint8_t data[];
|
||||
#endif
|
||||
} queue_state_t;
|
||||
|
||||
#define QUEUE_STATE_T_SIZE(len) (sizeof(queue_state_t) + len + 1)
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t30.h,v 1.114 2008/08/13 00:11:30 steveu Exp $
|
||||
* $Id: t30.h,v 1.115 2008/09/04 14:40:05 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -338,7 +338,7 @@ enum
|
||||
T30_SUPPORT_V29 = 0x02,
|
||||
T30_SUPPORT_V17 = 0x04,
|
||||
T30_SUPPORT_V34 = 0x08,
|
||||
T30_SUPPORT_IAF = 0x10,
|
||||
T30_SUPPORT_IAF = 0x10
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_core.h,v 1.28 2008/06/19 13:27:45 steveu Exp $
|
||||
* $Id: t38_core.h,v 1.29 2008/09/04 14:40:05 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -142,7 +142,7 @@ enum t38_field_classes_e
|
||||
{
|
||||
T38_FIELD_CLASS_NONE = 0,
|
||||
T38_FIELD_CLASS_HDLC,
|
||||
T38_FIELD_CLASS_NON_ECM,
|
||||
T38_FIELD_CLASS_NON_ECM
|
||||
};
|
||||
|
||||
/*! T.38 message types */
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_gateway.h,v 1.56 2008/08/14 14:06:05 steveu Exp $
|
||||
* $Id: t38_gateway.h,v 1.57 2008/09/02 13:56:10 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -125,6 +125,21 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*! \brief HDLC message buffers. */
|
||||
uint8_t buf[T38_MAX_HDLC_LEN];
|
||||
/*! \brief HDLC message lengths. */
|
||||
int len;
|
||||
/*! \brief HDLC message status flags. */
|
||||
int flags;
|
||||
/*! \brief HDLC buffer contents. */
|
||||
int contents;
|
||||
} t38_gateway_hdlc_buf_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*! \brief HDLC message buffers. */
|
||||
t38_gateway_hdlc_buf_t buf[T38_TX_HDLC_BUFS];
|
||||
#if 0
|
||||
/*! \brief HDLC message buffers. */
|
||||
uint8_t buf[T38_TX_HDLC_BUFS][T38_MAX_HDLC_LEN];
|
||||
/*! \brief HDLC message lengths. */
|
||||
@ -133,6 +148,7 @@ typedef struct
|
||||
int flags[T38_TX_HDLC_BUFS];
|
||||
/*! \brief HDLC buffer contents. */
|
||||
int contents[T38_TX_HDLC_BUFS];
|
||||
#endif
|
||||
/*! \brief HDLC buffer number for input. */
|
||||
int in;
|
||||
/*! \brief HDLC buffer number for output. */
|
||||
|
@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_non_ecm_buffer.h,v 1.1 2008/08/14 14:06:05 steveu Exp $
|
||||
* $Id: t38_non_ecm_buffer.h,v 1.2 2008/09/02 13:56:10 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -83,10 +83,13 @@ typedef struct
|
||||
|
||||
/*! \brief The number of octets input to the buffer. */
|
||||
int in_octets;
|
||||
/*! \brief The number of octets output from the buffer. */
|
||||
int out_octets;
|
||||
/*! \brief The number of rows input to the buffer. */
|
||||
int in_rows;
|
||||
/*! \brief The number of non-ECM fill octets generated for minimum row bits
|
||||
purposes. */
|
||||
int min_row_bits_fill_octets;
|
||||
/*! \brief The number of octets output from the buffer. */
|
||||
int out_octets;
|
||||
/*! \brief The number of rows output from the buffer. */
|
||||
int out_rows;
|
||||
/*! \brief The number of non-ECM fill octets generated for flow control
|
||||
@ -106,6 +109,12 @@ extern "C"
|
||||
\return A pointer to the buffer context, or NULL if there was a problem. */
|
||||
t38_non_ecm_buffer_state_t *t38_non_ecm_buffer_init(t38_non_ecm_buffer_state_t *s, int mode, int min_row_bits);
|
||||
|
||||
/*! \brief Set the mode of a T.38 rate adapting non-ECM buffer context.
|
||||
\param s The buffer context.
|
||||
\param mode TRUE for image data mode, or FALSE for TCF mode.
|
||||
\param bits The minimum number of bits per FAX image row. */
|
||||
void t38_non_ecm_buffer_set_mode(t38_non_ecm_buffer_state_t *s, int mode, int min_row_bits);
|
||||
|
||||
/*! \brief Inject data to T.38 rate adapting non-ECM buffer context.
|
||||
\param s The buffer context.
|
||||
\param buf The data buffer to be injected.
|
||||
@ -117,11 +126,17 @@ void t38_non_ecm_buffer_inject(t38_non_ecm_buffer_state_t *s, const uint8_t *buf
|
||||
\param s The buffer context. */
|
||||
void t38_non_ecm_buffer_push(t38_non_ecm_buffer_state_t *s);
|
||||
|
||||
/*! \brief Report the status of a T.38 rate adapting non-ECM buffer context to the specified
|
||||
/*! \brief Report the input status of a T.38 rate adapting non-ECM buffer context to the specified
|
||||
logging context.
|
||||
\param s The buffer context.
|
||||
\param logging The logging context. */
|
||||
void t38_non_ecm_buffer_report_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging);
|
||||
void t38_non_ecm_buffer_report_input_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging);
|
||||
|
||||
/*! \brief Report the output status of a T.38 rate adapting non-ECM buffer context to the specified
|
||||
logging context.
|
||||
\param s The buffer context.
|
||||
\param logging The logging context. */
|
||||
void t38_non_ecm_buffer_report_output_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging);
|
||||
|
||||
/*! \brief Get the next bit of data from a T.38 rate adapting non-ECM buffer context.
|
||||
\param user_data The buffer context, cast to a void pointer.
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v17rx.h,v 1.52 2008/07/16 14:23:48 steveu Exp $
|
||||
* $Id: v17rx.h,v 1.53 2008/09/08 12:54:32 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -306,28 +306,26 @@ typedef struct
|
||||
/*! \brief The previous value of agc_scaling, needed to reuse old training. */
|
||||
float agc_scaling_save;
|
||||
|
||||
/*! \brief The current delta factor for updating the equalizer coefficients. */
|
||||
float eq_delta;
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
/*! \brief The adaptive equalizer coefficients. */
|
||||
complexi_t eq_coeff[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||
complexi_t eq_coeff_save[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
||||
/*! \brief The equalizer signal buffer. */
|
||||
complexi_t eq_buf[V17_EQUALIZER_MASK + 1];
|
||||
#else
|
||||
complexf_t eq_coeff[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
||||
complexf_t eq_coeff_save[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
||||
complexf_t eq_buf[V17_EQUALIZER_MASK + 1];
|
||||
#endif
|
||||
/*! \brief Current read offset into the equalizer buffer. */
|
||||
int eq_step;
|
||||
/*! \brief Current write offset into the equalizer buffer. */
|
||||
int eq_put_step;
|
||||
/*! \brief Symbol counter to the next equalizer update. */
|
||||
int eq_skip;
|
||||
|
||||
/*! \brief The current half of the baud. */
|
||||
int baud_half;
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
/*! \brief The current delta factor for updating the equalizer coefficients. */
|
||||
float eq_delta;
|
||||
/*! \brief The adaptive equalizer coefficients. */
|
||||
complexi16_t eq_coeff[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||
complexi16_t eq_coeff_save[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
||||
/*! \brief The equalizer signal buffer. */
|
||||
complexi16_t eq_buf[V17_EQUALIZER_MASK + 1];
|
||||
|
||||
/*! Low band edge filter for symbol sync. */
|
||||
int32_t symbol_sync_low[2];
|
||||
/*! High band edge filter for symbol sync. */
|
||||
@ -337,6 +335,15 @@ typedef struct
|
||||
/*! Baud phase for symbol sync. */
|
||||
int32_t baud_phase;
|
||||
#else
|
||||
/*! \brief The current delta factor for updating the equalizer coefficients. */
|
||||
float eq_delta;
|
||||
/*! \brief The adaptive equalizer coefficients. */
|
||||
complexf_t eq_coeff[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||
complexf_t eq_coeff_save[V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN];
|
||||
/*! \brief The equalizer signal buffer. */
|
||||
complexf_t eq_buf[V17_EQUALIZER_MASK + 1];
|
||||
|
||||
/*! Low band edge filter for symbol sync. */
|
||||
float symbol_sync_low[2];
|
||||
/*! High band edge filter for symbol sync. */
|
||||
@ -346,6 +353,7 @@ typedef struct
|
||||
/*! Baud phase for symbol sync. */
|
||||
float baud_phase;
|
||||
#endif
|
||||
|
||||
/*! \brief The total symbol timing correction since the carrier came up.
|
||||
This is only for performance analysis purposes. */
|
||||
int total_baud_timing_correction;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v27ter_rx.h,v 1.47 2008/07/16 14:23:48 steveu Exp $
|
||||
* $Id: v27ter_rx.h,v 1.48 2008/09/08 12:54:32 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -144,22 +144,10 @@ typedef struct
|
||||
/*! \brief The previous value of agc_scaling, needed to reuse old training. */
|
||||
float agc_scaling_save;
|
||||
|
||||
/*! \brief The position of the current symbol in the constellation, used for
|
||||
differential decoding. */
|
||||
int constellation_state;
|
||||
|
||||
/*! \brief The current delta factor for updating the equalizer coefficients. */
|
||||
float eq_delta;
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
/*! \brief The adaptive equalizer coefficients. */
|
||||
complexi_t eq_coeff[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||
complexi_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
||||
/*! \brief The equalizer signal buffer. */
|
||||
complexi_t eq_buf[V27TER_EQUALIZER_MASK + 1];
|
||||
#else
|
||||
complexf_t eq_coeff[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
||||
complexf_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
||||
complexf_t eq_buf[V27TER_EQUALIZER_MASK + 1];
|
||||
#endif
|
||||
/*! \brief Current offset into the equalizer buffer. */
|
||||
int eq_step;
|
||||
/*! \brief Current write offset into the equalizer buffer. */
|
||||
@ -167,6 +155,29 @@ typedef struct
|
||||
/*! \brief Symbol counter to the next equalizer update. */
|
||||
int eq_skip;
|
||||
|
||||
/*! \brief The current half of the baud. */
|
||||
int baud_half;
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
/*! \brief The current delta factor for updating the equalizer coefficients. */
|
||||
float eq_delta;
|
||||
/*! \brief The adaptive equalizer coefficients. */
|
||||
complexi16_t eq_coeff[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||
complexi16_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
||||
/*! \brief The equalizer signal buffer. */
|
||||
complexi16_t eq_buf[V27TER_EQUALIZER_MASK + 1];
|
||||
#else
|
||||
/*! \brief The current delta factor for updating the equalizer coefficients. */
|
||||
float eq_delta;
|
||||
/*! \brief The adaptive equalizer coefficients. */
|
||||
complexf_t eq_coeff[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||
complexf_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN];
|
||||
/*! \brief The equalizer signal buffer. */
|
||||
complexf_t eq_buf[V27TER_EQUALIZER_MASK + 1];
|
||||
#endif
|
||||
|
||||
/*! \brief Integration variable for damping the Gardner algorithm tests. */
|
||||
int gardner_integrate;
|
||||
/*! \brief Current step size of Gardner algorithm integration. */
|
||||
@ -174,8 +185,6 @@ typedef struct
|
||||
/*! \brief The total symbol timing correction since the carrier came up.
|
||||
This is only for performance analysis purposes. */
|
||||
int total_baud_timing_correction;
|
||||
/*! \brief The current fractional phase of the baud timing. */
|
||||
int baud_phase;
|
||||
|
||||
/*! \brief Starting phase angles for the coarse carrier aquisition step. */
|
||||
int32_t start_angles[2];
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v29rx.h,v 1.55 2008/07/16 14:23:48 steveu Exp $
|
||||
* $Id: v29rx.h,v 1.59 2008/09/08 12:45:02 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -212,22 +212,10 @@ typedef struct
|
||||
/*! \brief The previous value of agc_scaling, needed to reuse old training. */
|
||||
float agc_scaling_save;
|
||||
|
||||
/*! \brief The position of the current symbol in the constellation, used for
|
||||
differential decoding. */
|
||||
int constellation_state;
|
||||
|
||||
/*! \brief The current delta factor for updating the equalizer coefficients. */
|
||||
float eq_delta;
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
/*! \brief The adaptive equalizer coefficients. */
|
||||
complexi_t eq_coeff[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||
complexi_t eq_coeff_save[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
||||
/*! \brief The equalizer signal buffer. */
|
||||
complexi_t eq_buf[V29_EQUALIZER_MASK + 1];
|
||||
#else
|
||||
complexf_t eq_coeff[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
||||
complexf_t eq_coeff_save[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
||||
complexf_t eq_buf[V29_EQUALIZER_MASK + 1];
|
||||
#endif
|
||||
/*! \brief Current offset into the equalizer buffer. */
|
||||
int eq_step;
|
||||
/*! \brief Current write offset into the equalizer buffer. */
|
||||
@ -237,7 +225,17 @@ typedef struct
|
||||
|
||||
/*! \brief The current half of the baud. */
|
||||
int baud_half;
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
/*! \brief The current delta factor for updating the equalizer coefficients. */
|
||||
int16_t eq_delta;
|
||||
/*! \brief The adaptive equalizer coefficients. */
|
||||
complexi16_t eq_coeff[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||
complexi16_t eq_coeff_save[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
||||
/*! \brief The equalizer signal buffer. */
|
||||
complexi16_t eq_buf[V29_EQUALIZER_MASK + 1];
|
||||
|
||||
/*! Low band edge filter for symbol sync. */
|
||||
int32_t symbol_sync_low[2];
|
||||
/*! High band edge filter for symbol sync. */
|
||||
@ -247,6 +245,15 @@ typedef struct
|
||||
/*! Baud phase for symbol sync. */
|
||||
int32_t baud_phase;
|
||||
#else
|
||||
/*! \brief The current delta factor for updating the equalizer coefficients. */
|
||||
float eq_delta;
|
||||
/*! \brief The adaptive equalizer coefficients. */
|
||||
complexf_t eq_coeff[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
||||
/*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */
|
||||
complexf_t eq_coeff_save[V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN];
|
||||
/*! \brief The equalizer signal buffer. */
|
||||
complexf_t eq_buf[V29_EQUALIZER_MASK + 1];
|
||||
|
||||
/*! Low band edge filter for symbol sync. */
|
||||
float symbol_sync_low[2];
|
||||
/*! High band edge filter for symbol sync. */
|
||||
@ -324,7 +331,11 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len);
|
||||
\param s The modem context.
|
||||
\param coeffs The vector of complex coefficients.
|
||||
\return The number of coefficients in the vector. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
int v29_rx_equalizer_state(v29_rx_state_t *s, complexi16_t **coeffs);
|
||||
#else
|
||||
int v29_rx_equalizer_state(v29_rx_state_t *s, complexf_t **coeffs);
|
||||
#endif
|
||||
|
||||
/*! Get the current received carrier frequency.
|
||||
\param s The modem context.
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v8.h,v 1.22 2008/05/14 15:41:25 steveu Exp $
|
||||
* $Id: v8.h,v 1.23 2008/09/04 14:40:05 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -76,7 +76,7 @@ enum v8_modulation_e
|
||||
V8_MOD_V90 = (1 << 12), /* V.90 duplex */
|
||||
V8_MOD_V92 = (1 << 13), /* V.92 duplex */
|
||||
|
||||
V8_MOD_FAILED = (1 << 15), /* Indicates failure to negotiate */
|
||||
V8_MOD_FAILED = (1 << 15) /* Indicates failure to negotiate */
|
||||
};
|
||||
|
||||
enum v8_protocol_e
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: vector_float.h,v 1.10 2008/04/17 14:27:01 steveu Exp $
|
||||
* $Id: vector_float.h,v 1.11 2008/09/01 16:07:34 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_VECTOR_FLOAT_H_)
|
||||
@ -105,11 +105,26 @@ void vec_mul(double z[], const double x[], const double y[], int n);
|
||||
void vec_mull(long double z[], const long double x[], const long double y[], int n);
|
||||
#endif
|
||||
|
||||
/*! \brief Find the dot product of two float vectors.
|
||||
\param x The first vector.
|
||||
\param y The first vector.
|
||||
\param n The number of elements in the vectors.
|
||||
\return The dot product of the two vectors. */
|
||||
float vec_dot_prodf(const float x[], const float y[], int n);
|
||||
|
||||
/*! \brief Find the dot product of two double vectors.
|
||||
\param x The first vector.
|
||||
\param y The first vector.
|
||||
\param n The number of elements in the vectors.
|
||||
\return The dot product of the two vectors. */
|
||||
double vec_dot_prod(const double x[], const double y[], int n);
|
||||
|
||||
#if defined(HAVE_LONG_DOUBLE)
|
||||
/*! \brief Find the dot product of two long double vectors.
|
||||
\param x The first vector.
|
||||
\param y The first vector.
|
||||
\param n The number of elements in the vectors.
|
||||
\return The dot product of the two vectors. */
|
||||
long double vec_dot_prodl(const long double x[], const long double y[], int n);
|
||||
#endif
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: vector_int.h,v 1.10 2008/04/17 14:27:01 steveu Exp $
|
||||
* $Id: vector_int.h,v 1.11 2008/09/01 16:07:34 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_VECTOR_INT_H_)
|
||||
@ -33,11 +33,79 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
static __inline__ void vec_copyi(int z[], const int x[], int n)
|
||||
{
|
||||
memcpy(z, x, n*sizeof(z[0]));
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ void vec_copyi16(int16_t z[], const int16_t x[], int n)
|
||||
{
|
||||
memcpy(z, x, n*sizeof(z[0]));
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ void vec_copyi32(int32_t z[], const int32_t x[], int n)
|
||||
{
|
||||
memcpy(z, x, n*sizeof(z[0]));
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ void vec_zeroi(int z[], int n)
|
||||
{
|
||||
memset(z, 0, n*sizeof(z[0]));
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ void vec_zeroi16(int16_t z[], int n)
|
||||
{
|
||||
memset(z, 0, n*sizeof(z[0]));
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ void vec_zeroi32(int32_t z[], int n)
|
||||
{
|
||||
memset(z, 0, n*sizeof(z[0]));
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ void vec_seti(int z[], int x, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
z[i] = x;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ void vec_seti16(int16_t z[], int16_t x, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
z[i] = x;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ void vec_seti32(int32_t z[], int32_t x, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
z[i] = x;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
/*! \brief Find the dot product of two int16_t vectors.
|
||||
\param x The first vector.
|
||||
\param y The first vector.
|
||||
\param n The number of elements in the vectors.
|
||||
\return The dot product of the two vectors. */
|
||||
int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n);
|
||||
|
||||
/*! \brief Find the minimum and maximum values in a vector.
|
||||
/*! \brief Find the minimum and maximum values in an int16_t vector.
|
||||
\param x The vector to be searched.
|
||||
\param n The number of elements in the vetor.
|
||||
\param n The number of elements in the vector.
|
||||
\param out A two element vector. The first will receive the
|
||||
maximum. The second will receive the minimum. This parameter
|
||||
may be set to NULL.
|
||||
|
@ -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 ------------------------------------------------------------*/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t30.c,v 1.262 2008/08/17 16:25:52 steveu Exp $
|
||||
* $Id: t30.c,v 1.264 2008/09/09 15:30:43 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -1831,7 +1831,6 @@ static int start_receiving_document(t30_state_t *s)
|
||||
}
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Start receiving document\n");
|
||||
queue_phase(s, T30_PHASE_B_TX);
|
||||
s->dis_received = FALSE;
|
||||
s->ecm_block = 0;
|
||||
send_dis_or_dtc_sequence(s, TRUE);
|
||||
return 0;
|
||||
@ -2006,7 +2005,6 @@ static int process_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
|
||||
send_dcn(s);
|
||||
return -1;
|
||||
}
|
||||
s->dis_received = TRUE;
|
||||
if (set_dis_or_dtc(s))
|
||||
{
|
||||
s->current_status = T30_ERR_INCOMPATIBLE;
|
||||
@ -4823,13 +4821,13 @@ static void t30_non_ecm_rx_status(void *user_data, int status)
|
||||
s = (t30_state_t *) user_data;
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
break;
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier training failed in state %d\n", s->state);
|
||||
s->rx_trained = FALSE;
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
/* The modem is now trained */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier trained in state %d\n", s->state);
|
||||
/* In case we are in trainability test mode... */
|
||||
@ -4840,10 +4838,10 @@ static void t30_non_ecm_rx_status(void *user_data, int status)
|
||||
s->rx_trained = TRUE;
|
||||
s->timer_t2_t4 = 0;
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier up in state %d\n", s->state);
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier down in state %d\n", s->state);
|
||||
was_trained = s->rx_trained;
|
||||
s->rx_signal_present = FALSE;
|
||||
@ -5052,7 +5050,7 @@ int t30_non_ecm_get_bit(void *user_data)
|
||||
if (s->tcf_test_bits-- < 0)
|
||||
{
|
||||
/* Finished sending training test. */
|
||||
bit = PUTBIT_END_OF_DATA;
|
||||
bit = SIG_STATUS_END_OF_DATA;
|
||||
}
|
||||
break;
|
||||
case T30_STATE_I:
|
||||
@ -5066,7 +5064,7 @@ int t30_non_ecm_get_bit(void *user_data)
|
||||
break;
|
||||
default:
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get_bit in bad state %d\n", s->state);
|
||||
bit = PUTBIT_END_OF_DATA;
|
||||
bit = SIG_STATUS_END_OF_DATA;
|
||||
break;
|
||||
}
|
||||
return bit;
|
||||
@ -5150,19 +5148,19 @@ static void t30_hdlc_rx_status(void *user_data, int status)
|
||||
s = (t30_state_t *) user_data;
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
break;
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier training failed in state %d\n", s->state);
|
||||
s->rx_trained = FALSE;
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
/* The modem is now trained */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier trained in state %d\n", s->state);
|
||||
s->rx_signal_present = TRUE;
|
||||
s->rx_trained = TRUE;
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier up in state %d\n", s->state);
|
||||
s->rx_signal_present = TRUE;
|
||||
switch (s->timer_t2_t4_is)
|
||||
@ -5177,7 +5175,7 @@ static void t30_hdlc_rx_status(void *user_data, int status)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier down in state %d\n", s->state);
|
||||
s->rx_signal_present = FALSE;
|
||||
s->rx_trained = FALSE;
|
||||
@ -5206,7 +5204,7 @@ static void t30_hdlc_rx_status(void *user_data, int status)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PUTBIT_FRAMING_OK:
|
||||
case SIG_STATUS_FRAMING_OK:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC framing OK in state %d\n", s->state);
|
||||
if (!s->far_end_detected && s->timer_t0_t1 > 0)
|
||||
{
|
||||
@ -5232,7 +5230,7 @@ static void t30_hdlc_rx_status(void *user_data, int status)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PUTBIT_ABORT:
|
||||
case SIG_STATUS_ABORT:
|
||||
/* Just ignore these */
|
||||
break;
|
||||
default:
|
||||
@ -5559,10 +5557,10 @@ void t30_front_end_status(void *user_data, int status)
|
||||
switch (s->phase)
|
||||
{
|
||||
case T30_PHASE_C_NON_ECM_RX:
|
||||
t30_non_ecm_rx_status(s, PUTBIT_CARRIER_DOWN);
|
||||
t30_non_ecm_rx_status(s, SIG_STATUS_CARRIER_DOWN);
|
||||
break;
|
||||
default:
|
||||
t30_hdlc_rx_status(s, PUTBIT_CARRIER_DOWN);
|
||||
t30_hdlc_rx_status(s, SIG_STATUS_CARRIER_DOWN);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -5584,8 +5582,8 @@ void t30_front_end_status(void *user_data, int status)
|
||||
case T30_PHASE_D_RX:
|
||||
/* We are running a V.21 receive modem, where an explicit training indication
|
||||
will not occur. */
|
||||
t30_hdlc_rx_status(s, PUTBIT_CARRIER_UP);
|
||||
t30_hdlc_rx_status(s, PUTBIT_FRAMING_OK);
|
||||
t30_hdlc_rx_status(s, SIG_STATUS_CARRIER_UP);
|
||||
t30_hdlc_rx_status(s, SIG_STATUS_FRAMING_OK);
|
||||
break;
|
||||
default:
|
||||
/* Cancel any receive timeout, and declare that a receive signal is present,
|
||||
|
@ -25,7 +25,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t31.c,v 1.119 2008/08/09 05:09:56 steveu Exp $
|
||||
* $Id: t31.c,v 1.120 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -341,7 +341,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
packets, when they have sent no data for the body of the frame. */
|
||||
if (s->tx.out_bytes > 0)
|
||||
hdlc_accept((void *) s, fe->hdlc_rx.buf, fe->hdlc_rx.len, TRUE);
|
||||
hdlc_accept((void *) s, NULL, PUTBIT_CARRIER_DOWN, TRUE);
|
||||
hdlc_accept((void *) s, NULL, SIG_STATUS_CARRIER_DOWN, TRUE);
|
||||
}
|
||||
s->tx.out_bytes = 0;
|
||||
fe->missing_data = FALSE;
|
||||
@ -352,7 +352,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD_SIG_END!\n");
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad, sig end (%s)\n", t30_frametype(s->tx.data[2]), (fe->missing_data) ? "missing octets" : "clean");
|
||||
if (fe->current_rx_type == T31_V21_RX)
|
||||
hdlc_accept((void *) s, NULL, PUTBIT_CARRIER_DOWN, TRUE);
|
||||
hdlc_accept((void *) s, NULL, SIG_STATUS_CARRIER_DOWN, TRUE);
|
||||
fe->hdlc_rx.len = 0;
|
||||
fe->missing_data = FALSE;
|
||||
break;
|
||||
@ -363,7 +363,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
i.e. they send T38_FIELD_HDLC_FCS_OK, and then T38_FIELD_HDLC_SIG_END when the carrier actually drops.
|
||||
The other is because the HDLC signal drops unexpectedly - i.e. not just after a final frame. */
|
||||
if (fe->current_rx_type == T31_V21_RX)
|
||||
hdlc_accept((void *) s, NULL, PUTBIT_CARRIER_DOWN, TRUE);
|
||||
hdlc_accept((void *) s, NULL, SIG_STATUS_CARRIER_DOWN, TRUE);
|
||||
fe->hdlc_rx.len = 0;
|
||||
fe->missing_data = FALSE;
|
||||
break;
|
||||
@ -709,20 +709,20 @@ static void non_ecm_rx_status(void *user_data, int status)
|
||||
s = (t31_state_t *) user_data;
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
break;
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
s->at_state.rx_trained = FALSE;
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
/* The modem is now trained */
|
||||
at_put_response_code(&s->at_state, AT_RESPONSE_CODE_CONNECT);
|
||||
s->at_state.rx_signal_present = TRUE;
|
||||
s->at_state.rx_trained = TRUE;
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
if (s->at_state.rx_signal_present)
|
||||
{
|
||||
s->at_state.rx_data[s->at_state.rx_data_bytes++] = DLE;
|
||||
@ -806,7 +806,7 @@ static int non_ecm_get_bit(void *user_data)
|
||||
s->tx.final = FALSE;
|
||||
/* This will put the modem into its shutdown sequence. When
|
||||
it has finally shut down, an OK response will be sent. */
|
||||
return PUTBIT_END_OF_DATA;
|
||||
return SIG_STATUS_END_OF_DATA;
|
||||
}
|
||||
/* Fill with 0xFF bytes at the start of transmission, or 0x00 if we are in
|
||||
the middle of transmission. This follows T.31 and T.30 practice. */
|
||||
@ -856,24 +856,24 @@ static void hdlc_rx_status(void *user_data, int status)
|
||||
s = (t31_state_t *) user_data;
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
break;
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
s->at_state.rx_trained = FALSE;
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
/* The modem is now trained */
|
||||
s->at_state.rx_signal_present = TRUE;
|
||||
s->at_state.rx_trained = TRUE;
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
if (s->modem == T31_CNG_TONE || s->modem == T31_NOCNG_TONE || s->modem == T31_V21_RX)
|
||||
{
|
||||
s->at_state.rx_signal_present = TRUE;
|
||||
s->rx_frame_received = FALSE;
|
||||
}
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
if (s->rx_frame_received)
|
||||
{
|
||||
if (s->at_state.dte_is_waiting)
|
||||
@ -899,7 +899,7 @@ static void hdlc_rx_status(void *user_data, int status)
|
||||
s->at_state.rx_signal_present = FALSE;
|
||||
s->at_state.rx_trained = FALSE;
|
||||
break;
|
||||
case PUTBIT_FRAMING_OK:
|
||||
case SIG_STATUS_FRAMING_OK:
|
||||
if (s->modem == T31_CNG_TONE || s->modem == T31_NOCNG_TONE)
|
||||
{
|
||||
/* Once we get any valid HDLC the CNG tone stops, and we drop
|
||||
@ -949,7 +949,7 @@ static void hdlc_rx_status(void *user_data, int status)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PUTBIT_ABORT:
|
||||
case SIG_STATUS_ABORT:
|
||||
/* Just ignore these */
|
||||
break;
|
||||
default:
|
||||
|
@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_gateway.c,v 1.139 2008/08/17 16:25:52 steveu Exp $
|
||||
* $Id: t38_gateway.c,v 1.142 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -308,31 +308,31 @@ static void hdlc_underflow_handler(void *user_data)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC underflow at %d\n", t->out);
|
||||
/* If the current HDLC buffer is not at the HDLC_FLAG_PROCEED_WITH_OUTPUT stage, this
|
||||
underflow must be an end of preamble condition. */
|
||||
if ((t->flags[t->out] & HDLC_FLAG_PROCEED_WITH_OUTPUT))
|
||||
if ((t->buf[t->out].flags & HDLC_FLAG_PROCEED_WITH_OUTPUT))
|
||||
{
|
||||
old_data_type = t->contents[t->out];
|
||||
t->len[t->out] = 0;
|
||||
t->flags[t->out] = 0;
|
||||
t->contents[t->out] = 0;
|
||||
old_data_type = t->buf[t->out].contents;
|
||||
t->buf[t->out].len = 0;
|
||||
t->buf[t->out].flags = 0;
|
||||
t->buf[t->out].contents = 0;
|
||||
if (++t->out >= T38_TX_HDLC_BUFS)
|
||||
t->out = 0;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC next is 0x%X\n", t->contents[t->out]);
|
||||
if ((t->contents[t->out] & FLAG_INDICATOR))
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC next is 0x%X\n", t->buf[t->out].contents);
|
||||
if ((t->buf[t->out].contents & FLAG_INDICATOR))
|
||||
{
|
||||
/* The next thing in the queue is an indicator, so we need to stop this modem. */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC shutdown\n");
|
||||
hdlc_tx_frame(&s->audio.modems.hdlc_tx, NULL, 0);
|
||||
}
|
||||
else if ((t->contents[t->out] & FLAG_DATA))
|
||||
else if ((t->buf[t->out].contents & FLAG_DATA))
|
||||
{
|
||||
/* Check if we should start sending the next frame */
|
||||
if ((t->flags[t->out] & HDLC_FLAG_PROCEED_WITH_OUTPUT))
|
||||
if ((t->buf[t->out].flags & HDLC_FLAG_PROCEED_WITH_OUTPUT))
|
||||
{
|
||||
/* This frame is ready to go, and uses the same modem we are running now. So, send
|
||||
whatever we have. This might or might not be an entire frame. */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC start next frame\n");
|
||||
hdlc_tx_frame(&s->audio.modems.hdlc_tx, t->buf[t->out], t->len[t->out]);
|
||||
if ((t->flags[t->out] & HDLC_FLAG_CORRUPT_CRC))
|
||||
hdlc_tx_frame(&s->audio.modems.hdlc_tx, t->buf[t->out].buf, t->buf[t->out].len);
|
||||
if ((t->buf[t->out].flags & HDLC_FLAG_CORRUPT_CRC))
|
||||
hdlc_tx_corrupt_frame(&s->audio.modems.hdlc_tx);
|
||||
/*endif*/
|
||||
}
|
||||
@ -355,9 +355,10 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
||||
|
||||
t = &s->audio.modems;
|
||||
u = &s->core.hdlc_to_modem;
|
||||
t38_non_ecm_buffer_report_output_status(&s->core.non_ecm_to_modem, &s->logging);
|
||||
if (t->next_tx_handler)
|
||||
{
|
||||
/* There is a handler queued, so that is the next one */
|
||||
/* There is a handler queued, so that is the next one. */
|
||||
t->tx_handler = t->next_tx_handler;
|
||||
t->tx_user_data = t->next_tx_user_data;
|
||||
t->next_tx_handler = NULL;
|
||||
@ -378,13 +379,13 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
||||
if (u->in == u->out)
|
||||
return FALSE;
|
||||
/*endif*/
|
||||
if ((u->contents[u->out] & FLAG_INDICATOR) == 0)
|
||||
if ((u->buf[u->out].contents & FLAG_INDICATOR) == 0)
|
||||
return FALSE;
|
||||
/*endif*/
|
||||
indicator = (u->contents[u->out] & 0xFF);
|
||||
u->len[u->out] = 0;
|
||||
u->flags[u->out] = 0;
|
||||
u->contents[u->out] = 0;
|
||||
indicator = (u->buf[u->out].contents & 0xFF);
|
||||
u->buf[u->out].len = 0;
|
||||
u->buf[u->out].flags = 0;
|
||||
u->buf[u->out].contents = 0;
|
||||
if (++u->out >= T38_TX_HDLC_BUFS)
|
||||
u->out = 0;
|
||||
/*endif*/
|
||||
@ -437,7 +438,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
||||
hdlc_tx_init(&t->hdlc_tx, FALSE, 2, TRUE, hdlc_underflow_handler, s);
|
||||
hdlc_tx_flags(&t->hdlc_tx, 32);
|
||||
silence_gen_alter(&t->silence_gen, ms_to_samples(75));
|
||||
u->len[u->in] = 0;
|
||||
u->buf[u->in].len = 0;
|
||||
fsk_tx_init(&t->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &t->hdlc_tx);
|
||||
t->tx_handler = (span_tx_handler_t *) &(silence_gen);
|
||||
t->tx_user_data = &t->silence_gen;
|
||||
@ -456,6 +457,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
||||
t->tx_bit_rate = 2400;
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
silence_gen_alter(&t->silence_gen, ms_to_samples(75));
|
||||
v27ter_tx_restart(&t->v27ter_tx, t->tx_bit_rate, t->use_tep);
|
||||
v27ter_tx_set_get_bit(&t->v27ter_tx, get_bit_func, get_bit_user_data);
|
||||
@ -476,6 +478,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
||||
t->tx_bit_rate = 9600;
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
silence_gen_alter(&t->silence_gen, ms_to_samples(75));
|
||||
v29_tx_restart(&t->v29_tx, t->tx_bit_rate, t->use_tep);
|
||||
v29_tx_set_get_bit(&t->v29_tx, get_bit_func, get_bit_user_data);
|
||||
@ -525,6 +528,7 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
||||
t->tx_bit_rate = 14400;
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
silence_gen_alter(&t->silence_gen, ms_to_samples(75));
|
||||
v17_tx_restart(&t->v17_tx, t->tx_bit_rate, t->use_tep, short_train);
|
||||
v17_tx_set_get_bit(&t->v17_tx, get_bit_func, get_bit_user_data);
|
||||
@ -563,36 +567,41 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
||||
if (t->tx_bit_rate > 300)
|
||||
hdlc_tx_flags(&t->hdlc_tx, t->tx_bit_rate/(8*5));
|
||||
/*endif*/
|
||||
t38_non_ecm_buffer_report_status(&s->core.non_ecm_to_modem, &s->logging);
|
||||
t38_non_ecm_buffer_init(&s->core.non_ecm_to_modem, s->core.image_data_mode, s->core.min_row_bits);
|
||||
s->t38x.in_progress_rx_indicator = indicator;
|
||||
return TRUE;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void pump_out_final_hdlc(t38_gateway_state_t *s, int good_fcs)
|
||||
static void finalise_hdlc_frame(t38_gateway_state_t *s, int good_fcs)
|
||||
{
|
||||
if (!good_fcs)
|
||||
s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] |= HDLC_FLAG_CORRUPT_CRC;
|
||||
t38_gateway_hdlc_buf_t *hdlc_buf;
|
||||
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
if (!good_fcs || (hdlc_buf->flags & HDLC_FLAG_MISSING_DATA))
|
||||
hdlc_buf->flags |= HDLC_FLAG_CORRUPT_CRC;
|
||||
/*endif*/
|
||||
if (s->core.hdlc_to_modem.in == s->core.hdlc_to_modem.out)
|
||||
{
|
||||
/* This is the frame in progress at the output. */
|
||||
if ((s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.out] & HDLC_FLAG_PROCEED_WITH_OUTPUT) == 0)
|
||||
if ((hdlc_buf->flags & HDLC_FLAG_PROCEED_WITH_OUTPUT) == 0)
|
||||
{
|
||||
/* Output of this frame has not yet begun. Throw it all out now. */
|
||||
hdlc_tx_frame(&s->audio.modems.hdlc_tx, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.out], s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.out]);
|
||||
hdlc_tx_frame(&s->audio.modems.hdlc_tx, hdlc_buf->buf, hdlc_buf->len);
|
||||
}
|
||||
/*endif*/
|
||||
if ((s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.out] & HDLC_FLAG_CORRUPT_CRC))
|
||||
if ((hdlc_buf->flags & HDLC_FLAG_CORRUPT_CRC))
|
||||
hdlc_tx_corrupt_frame(&s->audio.modems.hdlc_tx);
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] |= (HDLC_FLAG_PROCEED_WITH_OUTPUT | HDLC_FLAG_FINISHED);
|
||||
hdlc_buf->flags |= (HDLC_FLAG_PROCEED_WITH_OUTPUT | HDLC_FLAG_FINISHED);
|
||||
if (++s->core.hdlc_to_modem.in >= T38_TX_HDLC_BUFS)
|
||||
s->core.hdlc_to_modem.in = 0;
|
||||
/*endif*/
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
hdlc_buf->len = 0;
|
||||
hdlc_buf->flags = 0;
|
||||
hdlc_buf->contents = 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@ -853,53 +862,53 @@ static void monitor_control_messages(t38_gateway_state_t *s, int from_modem, uin
|
||||
static void queue_missing_indicator(t38_gateway_state_t *s, int data_type)
|
||||
{
|
||||
t38_core_state_t *t;
|
||||
int expected;
|
||||
int expected_alt;
|
||||
|
||||
t = &s->t38x.t38;
|
||||
expected = -1;
|
||||
expected_alt = -1;
|
||||
/* Missing packets might have lost us the indicator that should have put us in
|
||||
the required mode of operation. It might be a bit late to fill in such a gap
|
||||
now, but we should try. We may also want to force indicators into the queue,
|
||||
such as when the data says 'end of signal'. */
|
||||
/* We have an expectation of whether long or short training should occur, but be
|
||||
tolerant of either kind of indicator being present. */
|
||||
switch (data_type)
|
||||
{
|
||||
case T38_DATA_NONE:
|
||||
if (t->current_rx_indicator != T38_IND_NO_SIGNAL)
|
||||
process_rx_indicator(t, (void *) s, T38_IND_NO_SIGNAL);
|
||||
expected = T38_IND_NO_SIGNAL;
|
||||
break;
|
||||
case T38_DATA_V21:
|
||||
if (t->current_rx_indicator != T38_IND_V21_PREAMBLE)
|
||||
process_rx_indicator(t, (void *) s, T38_IND_V21_PREAMBLE);
|
||||
expected = T38_IND_V21_PREAMBLE;
|
||||
break;
|
||||
case T38_DATA_V27TER_2400:
|
||||
if (t->current_rx_indicator != T38_IND_V27TER_2400_TRAINING)
|
||||
process_rx_indicator(t, (void *) s, T38_IND_V27TER_2400_TRAINING);
|
||||
expected = T38_IND_V27TER_2400_TRAINING;
|
||||
break;
|
||||
case T38_DATA_V27TER_4800:
|
||||
if (t->current_rx_indicator != T38_IND_V27TER_4800_TRAINING)
|
||||
process_rx_indicator(t, (void *) s, T38_IND_V27TER_4800_TRAINING);
|
||||
expected = T38_IND_V27TER_4800_TRAINING;
|
||||
break;
|
||||
case T38_DATA_V29_7200:
|
||||
if (t->current_rx_indicator != T38_IND_V29_7200_TRAINING)
|
||||
process_rx_indicator(t, (void *) s, T38_IND_V29_7200_TRAINING);
|
||||
expected = T38_IND_V29_7200_TRAINING;
|
||||
break;
|
||||
case T38_DATA_V29_9600:
|
||||
if (t->current_rx_indicator != T38_IND_V29_9600_TRAINING)
|
||||
process_rx_indicator(t, (void *) s, T38_IND_V29_9600_TRAINING);
|
||||
expected = T38_IND_V29_9600_TRAINING;
|
||||
break;
|
||||
case T38_DATA_V17_7200:
|
||||
if (t->current_rx_indicator != T38_IND_V17_7200_SHORT_TRAINING && t->current_rx_indicator != T38_IND_V17_7200_LONG_TRAINING)
|
||||
process_rx_indicator(t, (void *) s, T38_IND_V17_7200_LONG_TRAINING);
|
||||
expected = (s->core.short_train) ? T38_IND_V17_7200_SHORT_TRAINING : T38_IND_V17_7200_LONG_TRAINING;
|
||||
expected_alt = (s->core.short_train) ? T38_IND_V17_7200_LONG_TRAINING : T38_IND_V17_7200_SHORT_TRAINING;
|
||||
break;
|
||||
case T38_DATA_V17_9600:
|
||||
if (t->current_rx_indicator != T38_IND_V17_9600_SHORT_TRAINING && t->current_rx_indicator != T38_IND_V17_9600_LONG_TRAINING)
|
||||
process_rx_indicator(t, (void *) s, T38_IND_V17_9600_LONG_TRAINING);
|
||||
expected = (s->core.short_train) ? T38_IND_V17_9600_SHORT_TRAINING : T38_IND_V17_9600_LONG_TRAINING;
|
||||
expected_alt = (s->core.short_train) ? T38_IND_V17_9600_LONG_TRAINING : T38_IND_V17_9600_SHORT_TRAINING;
|
||||
break;
|
||||
case T38_DATA_V17_12000:
|
||||
if (t->current_rx_indicator != T38_IND_V17_12000_SHORT_TRAINING && t->current_rx_indicator != T38_IND_V17_12000_LONG_TRAINING)
|
||||
process_rx_indicator(t, (void *) s, T38_IND_V17_12000_LONG_TRAINING);
|
||||
expected = (s->core.short_train) ? T38_IND_V17_12000_SHORT_TRAINING : T38_IND_V17_12000_LONG_TRAINING;
|
||||
expected_alt = (s->core.short_train) ? T38_IND_V17_12000_LONG_TRAINING : T38_IND_V17_12000_SHORT_TRAINING;
|
||||
break;
|
||||
case T38_DATA_V17_14400:
|
||||
if (t->current_rx_indicator != T38_IND_V17_14400_SHORT_TRAINING && t->current_rx_indicator != T38_IND_V17_14400_LONG_TRAINING)
|
||||
process_rx_indicator(t, (void *) s, T38_IND_V17_14400_LONG_TRAINING);
|
||||
expected = (s->core.short_train) ? T38_IND_V17_14400_SHORT_TRAINING : T38_IND_V17_14400_LONG_TRAINING;
|
||||
expected_alt = (s->core.short_train) ? T38_IND_V17_14400_LONG_TRAINING : T38_IND_V17_14400_SHORT_TRAINING;
|
||||
break;
|
||||
case T38_DATA_V8:
|
||||
break;
|
||||
@ -914,6 +923,20 @@ static void queue_missing_indicator(t38_gateway_state_t *s, int data_type)
|
||||
case T38_DATA_V33_14400:
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
if (expected < 0)
|
||||
return;
|
||||
if (t->current_rx_indicator == expected)
|
||||
return;
|
||||
if (expected_alt >= 0 && t->current_rx_indicator == expected_alt)
|
||||
return;
|
||||
span_log(&s->logging,
|
||||
SPAN_LOG_FLOW,
|
||||
"Queuing missing indicator - %s\n",
|
||||
t38_indicator_to_str(expected));
|
||||
process_rx_indicator(t, (void *) s, expected);
|
||||
/* Force the indicator setting here, as the core won't set in when its missing. */
|
||||
t->current_rx_indicator = expected;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@ -922,7 +945,7 @@ static int process_rx_missing(t38_core_state_t *t, void *user_data, int rx_seq_n
|
||||
t38_gateway_state_t *s;
|
||||
|
||||
s = (t38_gateway_state_t *) user_data;
|
||||
s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] |= HDLC_FLAG_MISSING_DATA;
|
||||
s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in].flags |= HDLC_FLAG_MISSING_DATA;
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -933,23 +956,26 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
|
||||
|
||||
s = (t38_gateway_state_t *) user_data;
|
||||
|
||||
t38_non_ecm_buffer_report_input_status(&s->core.non_ecm_to_modem, &s->logging);
|
||||
if (t->current_rx_indicator == indicator)
|
||||
{
|
||||
/* This is probably due to the far end repeating itself. Ignore it. Its harmless */
|
||||
return 0;
|
||||
}
|
||||
/*endif*/
|
||||
if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in])
|
||||
if (s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in].contents)
|
||||
{
|
||||
if (++s->core.hdlc_to_modem.in >= T38_TX_HDLC_BUFS)
|
||||
s->core.hdlc_to_modem.in = 0;
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (indicator | FLAG_INDICATOR);
|
||||
s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in].contents = (indicator | FLAG_INDICATOR);
|
||||
if (++s->core.hdlc_to_modem.in >= T38_TX_HDLC_BUFS)
|
||||
s->core.hdlc_to_modem.in = 0;
|
||||
/*endif*/
|
||||
t38_non_ecm_buffer_set_mode(&s->core.non_ecm_to_modem, s->core.image_data_mode, s->core.min_row_bits);
|
||||
|
||||
span_log(&s->logging,
|
||||
SPAN_LOG_FLOW,
|
||||
"Queued change - (%d) %s -> %s\n",
|
||||
@ -967,9 +993,9 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
|
||||
static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, int field_type, const uint8_t *buf, int len)
|
||||
{
|
||||
int i;
|
||||
int previous;
|
||||
t38_gateway_state_t *s;
|
||||
t38_gateway_t38_state_t *xx;
|
||||
t38_gateway_hdlc_buf_t *hdlc_buf;
|
||||
|
||||
s = (t38_gateway_state_t *) user_data;
|
||||
xx = &s->t38x;
|
||||
@ -977,46 +1003,52 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
{
|
||||
case T38_FIELD_HDLC_DATA:
|
||||
xx->current_rx_field_class = T38_FIELD_CLASS_HDLC;
|
||||
if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA))
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
if (hdlc_buf->contents != (data_type | FLAG_DATA))
|
||||
{
|
||||
queue_missing_indicator(s, data_type);
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
}
|
||||
/*endif*/
|
||||
previous = s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in];
|
||||
/* Check if this data would overflow the buffer. */
|
||||
if (s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] + len > T38_MAX_HDLC_LEN)
|
||||
if (hdlc_buf->len + len > T38_MAX_HDLC_LEN)
|
||||
break;
|
||||
/*endif*/
|
||||
s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (data_type | FLAG_DATA);
|
||||
bit_reverse(&s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in][s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in]], buf, len);
|
||||
hdlc_buf->contents = (data_type | FLAG_DATA);
|
||||
bit_reverse(&hdlc_buf->buf[hdlc_buf->len], buf, len);
|
||||
/* We need to send out the control messages as they are arriving. They are
|
||||
too slow to capture a whole frame, and then pass it on.
|
||||
too slow to capture a whole frame before starting to pass it on.
|
||||
For the faster frames, take in the whole frame before sending it out. Also, there
|
||||
is no need to monitor, or modify, the contents of the faster frames. */
|
||||
if (data_type == T38_DATA_V21)
|
||||
{
|
||||
for (i = 1; i <= len; i++)
|
||||
edit_control_messages(s, 0, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in], s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] + i);
|
||||
edit_control_messages(s, 0, hdlc_buf->buf, hdlc_buf->len + i);
|
||||
/*endfor*/
|
||||
/* Don't start pumping data into the actual output stream until there is
|
||||
enough backlog to create some elasticity for jitter tolerance. */
|
||||
if (s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] + len >= HDLC_START_BUFFER_LEVEL)
|
||||
if (hdlc_buf->len + len >= HDLC_START_BUFFER_LEVEL)
|
||||
{
|
||||
if (s->core.hdlc_to_modem.in == s->core.hdlc_to_modem.out)
|
||||
{
|
||||
if ((s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] & HDLC_FLAG_PROCEED_WITH_OUTPUT) == 0)
|
||||
previous = 0;
|
||||
/* Output is not running, so kick it into life. */
|
||||
if ((hdlc_buf->flags & HDLC_FLAG_PROCEED_WITH_OUTPUT) == 0)
|
||||
hdlc_tx_frame(&s->audio.modems.hdlc_tx, hdlc_buf->buf, hdlc_buf->len + len);
|
||||
else
|
||||
hdlc_tx_frame(&s->audio.modems.hdlc_tx, hdlc_buf->buf + hdlc_buf->len, len);
|
||||
/*endif*/
|
||||
hdlc_tx_frame(&s->audio.modems.hdlc_tx, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.out] + previous, s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.out] - previous + len);
|
||||
}
|
||||
/*endif*/
|
||||
s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] |= HDLC_FLAG_PROCEED_WITH_OUTPUT;
|
||||
hdlc_buf->flags |= HDLC_FLAG_PROCEED_WITH_OUTPUT;
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] += len;
|
||||
s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in].len += len;
|
||||
break;
|
||||
case T38_FIELD_HDLC_FCS_OK:
|
||||
xx->current_rx_field_class = T38_FIELD_CLASS_HDLC;
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
if (len > 0)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK!\n");
|
||||
@ -1027,22 +1059,22 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
/* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK messages, in IFP packets with
|
||||
incrementing sequence numbers, which are actually repeats. They get through to this point because
|
||||
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
|
||||
if (t->current_rx_data_type != data_type
|
||||
||
|
||||
t->current_rx_field_type != field_type)
|
||||
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC good\n", t30_frametype(s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in][2]));
|
||||
if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA))
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC good\n", t30_frametype(hdlc_buf->buf[2]));
|
||||
if (hdlc_buf->contents != (data_type | FLAG_DATA))
|
||||
{
|
||||
queue_missing_indicator(s, data_type);
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
}
|
||||
/*endif*/
|
||||
s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (data_type | FLAG_DATA);
|
||||
if (data_type == T38_DATA_V21)
|
||||
{
|
||||
if ((s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] & HDLC_FLAG_MISSING_DATA) == 0)
|
||||
if ((hdlc_buf->flags & HDLC_FLAG_MISSING_DATA) == 0)
|
||||
{
|
||||
monitor_control_messages(s, FALSE, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in], s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in]);
|
||||
monitor_control_messages(s, FALSE, hdlc_buf->buf, hdlc_buf->len);
|
||||
if (s->core.real_time_frame_handler)
|
||||
s->core.real_time_frame_handler(s, s->core.real_time_frame_user_data, FALSE, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in], s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in]);
|
||||
s->core.real_time_frame_handler(s, s->core.real_time_frame_user_data, FALSE, hdlc_buf->buf, hdlc_buf->len);
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
@ -1050,21 +1082,21 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
else
|
||||
{
|
||||
/* Make sure we go back to short training if CTC/CTR has kicked us into
|
||||
long training. Theer has to be more than one value HDLC frame in a
|
||||
chunk of image data, so just setting short training mode heer should
|
||||
long training. There has to be more than one value HDLC frame in a
|
||||
chunk of image data, so just setting short training mode here should
|
||||
be enough. */
|
||||
s->core.short_train = TRUE;
|
||||
}
|
||||
/*endif*/
|
||||
pump_out_final_hdlc(s, (s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] & HDLC_FLAG_MISSING_DATA) == 0);
|
||||
hdlc_buf->contents = (data_type | FLAG_DATA);
|
||||
finalise_hdlc_frame(s, TRUE);
|
||||
}
|
||||
/*endif*/
|
||||
s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] = 0;
|
||||
s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] = 0;
|
||||
xx->corrupt_current_frame[0] = FALSE;
|
||||
break;
|
||||
case T38_FIELD_HDLC_FCS_BAD:
|
||||
xx->current_rx_field_class = T38_FIELD_CLASS_HDLC;
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
if (len > 0)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD!\n");
|
||||
@ -1077,24 +1109,32 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
|
||||
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC bad\n", t30_frametype(s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in][2]));
|
||||
if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA))
|
||||
queue_missing_indicator(s, data_type);
|
||||
/*endif*/
|
||||
if (s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] > 0)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC bad\n", t30_frametype(hdlc_buf->buf[2]));
|
||||
/* Only bother with frames that have a bad CRC, if they also have some content. */
|
||||
if (hdlc_buf->len > 0)
|
||||
{
|
||||
s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (data_type | FLAG_DATA);
|
||||
pump_out_final_hdlc(s, FALSE);
|
||||
if (hdlc_buf->contents != (data_type | FLAG_DATA))
|
||||
{
|
||||
queue_missing_indicator(s, data_type);
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
}
|
||||
/*endif*/
|
||||
hdlc_buf->contents = (data_type | FLAG_DATA);
|
||||
finalise_hdlc_frame(s, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just restart using the current frame buffer */
|
||||
hdlc_buf->contents = 0;
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] = 0;
|
||||
s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] = 0;
|
||||
xx->corrupt_current_frame[0] = FALSE;
|
||||
break;
|
||||
case T38_FIELD_HDLC_FCS_OK_SIG_END:
|
||||
xx->current_rx_field_class = T38_FIELD_CLASS_HDLC;
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
if (len > 0)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK_SIG_END!\n");
|
||||
@ -1107,23 +1147,35 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
|
||||
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC OK, sig end\n", t30_frametype(s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in][2]));
|
||||
if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA))
|
||||
queue_missing_indicator(s, data_type);
|
||||
/*endif*/
|
||||
s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (data_type | FLAG_DATA);
|
||||
if (data_type == T38_DATA_V21 && (s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] & HDLC_FLAG_MISSING_DATA) == 0)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC OK, sig end\n", t30_frametype(hdlc_buf->buf[2]));
|
||||
if (hdlc_buf->contents != (data_type | FLAG_DATA))
|
||||
{
|
||||
monitor_control_messages(s, FALSE, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in], s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in]);
|
||||
if (s->core.real_time_frame_handler)
|
||||
s->core.real_time_frame_handler(s, s->core.real_time_frame_user_data, FALSE, s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in], s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in]);
|
||||
/*endif*/
|
||||
queue_missing_indicator(s, data_type);
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
}
|
||||
/*endif*/
|
||||
pump_out_final_hdlc(s, (s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] & HDLC_FLAG_MISSING_DATA) == 0);
|
||||
s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] = 0;
|
||||
s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] = 0;
|
||||
s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = 0;
|
||||
if (data_type == T38_DATA_V21)
|
||||
{
|
||||
if ((hdlc_buf->flags & HDLC_FLAG_MISSING_DATA) == 0)
|
||||
{
|
||||
monitor_control_messages(s, FALSE, hdlc_buf->buf, hdlc_buf->len);
|
||||
if (s->core.real_time_frame_handler)
|
||||
s->core.real_time_frame_handler(s, s->core.real_time_frame_user_data, FALSE, hdlc_buf->buf, hdlc_buf->len);
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make sure we go back to short training if CTC/CTR has kicked us into
|
||||
long training. There has to be more than one value HDLC frame in a
|
||||
chunk of image data, so just setting short training mode here should
|
||||
be enough. */
|
||||
s->core.short_train = TRUE;
|
||||
}
|
||||
/*endif*/
|
||||
hdlc_buf->contents = (data_type | FLAG_DATA);
|
||||
finalise_hdlc_frame(s, TRUE);
|
||||
queue_missing_indicator(s, T38_DATA_NONE);
|
||||
xx->current_rx_field_class = T38_FIELD_CLASS_NONE;
|
||||
}
|
||||
@ -1132,6 +1184,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
break;
|
||||
case T38_FIELD_HDLC_FCS_BAD_SIG_END:
|
||||
xx->current_rx_field_class = T38_FIELD_CLASS_HDLC;
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
if (len > 0)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD_SIG_END!\n");
|
||||
@ -1144,19 +1197,25 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
|
||||
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC bad, sig end\n", t30_frametype(s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in][2]));
|
||||
if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA))
|
||||
queue_missing_indicator(s, data_type);
|
||||
/*endif*/
|
||||
if (s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] > 0)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC frame type %s - CRC bad, sig end\n", t30_frametype(hdlc_buf->buf[2]));
|
||||
if (hdlc_buf->contents != (data_type | FLAG_DATA))
|
||||
{
|
||||
s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = (data_type | FLAG_DATA);
|
||||
pump_out_final_hdlc(s, FALSE);
|
||||
queue_missing_indicator(s, data_type);
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
}
|
||||
/*endif*/
|
||||
/* Only bother with frames that have a bad CRC, if they also have some content. */
|
||||
if (hdlc_buf->len > 0)
|
||||
{
|
||||
hdlc_buf->contents = (data_type | FLAG_DATA);
|
||||
finalise_hdlc_frame(s, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just restart using the current frame buffer */
|
||||
hdlc_buf->contents = 0;
|
||||
}
|
||||
/*endif*/
|
||||
s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] = 0;
|
||||
s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] = 0;
|
||||
s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = 0;
|
||||
queue_missing_indicator(s, T38_DATA_NONE);
|
||||
xx->current_rx_field_class = T38_FIELD_CLASS_NONE;
|
||||
}
|
||||
@ -1164,6 +1223,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
xx->corrupt_current_frame[0] = FALSE;
|
||||
break;
|
||||
case T38_FIELD_HDLC_SIG_END:
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
if (len > 0)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_SIG_END!\n");
|
||||
@ -1176,8 +1236,11 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
|
||||
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type)
|
||||
{
|
||||
if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA))
|
||||
if (hdlc_buf->contents != (data_type | FLAG_DATA))
|
||||
{
|
||||
queue_missing_indicator(s, data_type);
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
}
|
||||
/* WORKAROUND: At least some Mediatrix boxes have a bug, where they can send this message at the
|
||||
end of non-ECM data. We need to tolerate this. */
|
||||
if (xx->current_rx_field_class == T38_FIELD_CLASS_NON_ECM)
|
||||
@ -1190,10 +1253,12 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
{
|
||||
/* This message is expected under 2 circumstances. One is as an alternative to T38_FIELD_HDLC_FCS_OK_SIG_END -
|
||||
i.e. they send T38_FIELD_HDLC_FCS_OK, and then T38_FIELD_HDLC_SIG_END when the carrier actually drops.
|
||||
The other is because the HDLC signal drops unexpectedly - i.e. not just after a final frame. */
|
||||
s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] = 0;
|
||||
s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] = 0;
|
||||
s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = 0;
|
||||
The other is because the HDLC signal drops unexpectedly - i.e. not just after a final frame. In
|
||||
this case we just clear out any partial frame data that might be in the buffer. */
|
||||
/* TODO: what if any junk in the buffer has reached the HDLC_FLAG_PROCEED_WITH_OUTPUT stage? */
|
||||
hdlc_buf->len = 0;
|
||||
hdlc_buf->flags = 0;
|
||||
hdlc_buf->contents = 0;
|
||||
}
|
||||
/*endif*/
|
||||
queue_missing_indicator(s, T38_DATA_NONE);
|
||||
@ -1204,12 +1269,17 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
break;
|
||||
case T38_FIELD_T4_NON_ECM_DATA:
|
||||
xx->current_rx_field_class = T38_FIELD_CLASS_NON_ECM;
|
||||
if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA))
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
if (hdlc_buf->contents != (data_type | FLAG_DATA))
|
||||
{
|
||||
queue_missing_indicator(s, data_type);
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
}
|
||||
t38_non_ecm_buffer_inject(&s->core.non_ecm_to_modem, buf, len);
|
||||
xx->corrupt_current_frame[0] = FALSE;
|
||||
break;
|
||||
case T38_FIELD_T4_NON_ECM_SIG_END:
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
/* Some T.38 implementations send multiple T38_FIELD_T4_NON_ECM_SIG_END messages, in IFP packets with
|
||||
incrementing sequence numbers, which are actually repeats. They get through to this point because
|
||||
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
|
||||
@ -1222,14 +1292,20 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
{
|
||||
if (len > 0)
|
||||
{
|
||||
if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA))
|
||||
if (hdlc_buf->contents != (data_type | FLAG_DATA))
|
||||
{
|
||||
queue_missing_indicator(s, data_type);
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
}
|
||||
/*endif*/
|
||||
t38_non_ecm_buffer_inject(&s->core.non_ecm_to_modem, buf, len);
|
||||
}
|
||||
/*endif*/
|
||||
if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA))
|
||||
if (hdlc_buf->contents != (data_type | FLAG_DATA))
|
||||
{
|
||||
queue_missing_indicator(s, data_type);
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
}
|
||||
/*endif*/
|
||||
/* Don't flow control the data any more. Just pump out the remainder as fast as we can. */
|
||||
t38_non_ecm_buffer_push(&s->core.non_ecm_to_modem);
|
||||
@ -1237,12 +1313,16 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
else
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "T38_FIELD_NON_ECM_SIG_END received at the end of HDLC data!\n");
|
||||
if (s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] != (data_type | FLAG_DATA))
|
||||
if (s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in].contents != (data_type | FLAG_DATA))
|
||||
{
|
||||
queue_missing_indicator(s, data_type);
|
||||
hdlc_buf = &s->core.hdlc_to_modem.buf[s->core.hdlc_to_modem.in];
|
||||
}
|
||||
/*endif*/
|
||||
s->core.hdlc_to_modem.len[s->core.hdlc_to_modem.in] = 0;
|
||||
s->core.hdlc_to_modem.flags[s->core.hdlc_to_modem.in] = 0;
|
||||
s->core.hdlc_to_modem.contents[s->core.hdlc_to_modem.in] = 0;
|
||||
/* TODO: what if any junk in the buffer has reached the HDLC_FLAG_PROCEED_WITH_OUTPUT stage? */
|
||||
hdlc_buf->len = 0;
|
||||
hdlc_buf->flags = 0;
|
||||
hdlc_buf->contents = 0;
|
||||
}
|
||||
/*endif*/
|
||||
queue_missing_indicator(s, T38_DATA_NONE);
|
||||
@ -1408,27 +1488,27 @@ static void non_ecm_rx_status(void *user_data, int status)
|
||||
s = (t38_gateway_state_t *) user_data;
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier training in progress\n");
|
||||
if (s->core.tcf_mode_predictable_modem_start)
|
||||
s->core.tcf_mode_predictable_modem_start = 0;
|
||||
else
|
||||
announce_training(s);
|
||||
break;
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
/* The modem is now trained */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier trained\n");
|
||||
s->audio.modems.rx_signal_present = TRUE;
|
||||
s->audio.modems.rx_trained = TRUE;
|
||||
to_t38_buffer_init(&s->core.to_t38);
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier down\n");
|
||||
s->core.tcf_mode_predictable_modem_start = 0;
|
||||
switch (s->t38x.current_tx_data_type)
|
||||
@ -1573,26 +1653,23 @@ static void hdlc_rx_status(hdlc_rx_state_t *t, int status)
|
||||
t38_gateway_state_t *s;
|
||||
|
||||
s = (t38_gateway_state_t *) t->user_data;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier training in progress\n");
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
announce_training(s);
|
||||
break;
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier training failed\n");
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
/* The modem is now trained. */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier trained\n");
|
||||
s->audio.modems.rx_signal_present = TRUE;
|
||||
s->audio.modems.rx_trained = TRUE;
|
||||
/* Behave like HDLC preamble has been announced. */
|
||||
t->framing_ok_announced = TRUE;
|
||||
to_t38_buffer_init(&s->core.to_t38);
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier up\n");
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
/* Reset the HDLC receiver. */
|
||||
t->raw_bit_stream = 0;
|
||||
t->len = 0;
|
||||
@ -1601,8 +1678,7 @@ static void hdlc_rx_status(hdlc_rx_state_t *t, int status)
|
||||
t->framing_ok_announced = FALSE;
|
||||
to_t38_buffer_init(&s->core.to_t38);
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier down\n");
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
if (t->framing_ok_announced)
|
||||
{
|
||||
t38_core_send_data(&s->t38x.t38, s->t38x.current_tx_data_type, T38_FIELD_HDLC_SIG_END, NULL, 0, s->t38x.t38.data_end_tx_count);
|
||||
|
@ -23,7 +23,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_non_ecm_buffer.c,v 1.1 2008/08/14 14:06:05 steveu Exp $
|
||||
* $Id: t38_non_ecm_buffer.c,v 1.3 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -59,6 +59,21 @@
|
||||
|
||||
#include "spandsp/t38_non_ecm_buffer.h"
|
||||
|
||||
static void restart_buffer(t38_non_ecm_buffer_state_t *s)
|
||||
{
|
||||
/* This should be called when draining the buffer is complete, which should
|
||||
occur before any fresh data can possibly arrive to begin refilling it. */
|
||||
s->octet = 0xFF;
|
||||
s->flow_control_fill_octet = 0xFF;
|
||||
s->at_initial_all_ones = TRUE;
|
||||
s->bit_stream = 0xFFFF;
|
||||
s->out_ptr = 0;
|
||||
s->in_ptr = 0;
|
||||
s->latest_eol_ptr = 0;
|
||||
s->data_finished = FALSE;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
int t38_non_ecm_buffer_get_bit(void *user_data)
|
||||
{
|
||||
t38_non_ecm_buffer_state_t *s;
|
||||
@ -80,12 +95,8 @@ int t38_non_ecm_buffer_get_bit(void *user_data)
|
||||
{
|
||||
/* The queue is empty, and we have received the end of data signal. This must
|
||||
really be the end to transmission. */
|
||||
s->data_finished = FALSE;
|
||||
/* Reset the data pointers for next time. */
|
||||
s->out_ptr = 0;
|
||||
s->in_ptr = 0;
|
||||
s->latest_eol_ptr = 0;
|
||||
return PUTBIT_END_OF_DATA;
|
||||
restart_buffer(s);
|
||||
return SIG_STATUS_END_OF_DATA;
|
||||
}
|
||||
/* The queue is blocked, but this does not appear to be the end of the data. Idle with
|
||||
fill octets, which should be safe at this point. */
|
||||
@ -160,10 +171,11 @@ void t38_non_ecm_buffer_inject(t38_non_ecm_buffer_state_t *s, const uint8_t *buf
|
||||
rough approach. */
|
||||
while (s->row_bits < s->min_row_bits)
|
||||
{
|
||||
s->min_row_bits_fill_octets++;
|
||||
s->data[s->in_ptr] = 0;
|
||||
s->row_bits += 8;
|
||||
/* TODO: We can't buffer overflow, since we wrap around. However, the tail could overwrite
|
||||
itself if things fall badly behind. */
|
||||
/* TODO: We can't buffer overflow, since we wrap around. However, the tail could
|
||||
overwrite itself if things fall badly behind. */
|
||||
s->in_ptr = (s->in_ptr + 1) & (T38_NON_ECM_TX_BUF_LEN - 1);
|
||||
}
|
||||
/* Start a new row */
|
||||
@ -205,28 +217,47 @@ void t38_non_ecm_buffer_inject(t38_non_ecm_buffer_state_t *s, const uint8_t *buf
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
void t38_non_ecm_buffer_report_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging)
|
||||
void t38_non_ecm_buffer_report_input_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging)
|
||||
{
|
||||
if (s->in_octets || s->out_octets)
|
||||
if (s->in_octets || s->min_row_bits_fill_octets)
|
||||
{
|
||||
span_log(logging,
|
||||
SPAN_LOG_FLOW,
|
||||
"%d incoming non-ECM octets, %d rows. %d outgoing non-ECM octets, %d rows\n",
|
||||
"%d+%d incoming non-ECM octets, %d rows.\n",
|
||||
s->in_octets,
|
||||
s->in_rows,
|
||||
s->out_octets,
|
||||
s->out_rows);
|
||||
s->min_row_bits_fill_octets,
|
||||
s->in_rows);
|
||||
s->in_octets = 0;
|
||||
s->in_rows = 0;
|
||||
s->min_row_bits_fill_octets = 0;
|
||||
}
|
||||
if (s->flow_control_fill_octets)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
void t38_non_ecm_buffer_report_output_status(t38_non_ecm_buffer_state_t *s, logging_state_t *logging)
|
||||
{
|
||||
if (s->out_octets || s->flow_control_fill_octets)
|
||||
{
|
||||
span_log(logging,
|
||||
SPAN_LOG_FLOW,
|
||||
"Non-ECM flow control generated %d octets\n",
|
||||
s->flow_control_fill_octets);
|
||||
"%d+%d outgoing non-ECM octets, %d rows.\n",
|
||||
s->out_octets - s->flow_control_fill_octets,
|
||||
s->flow_control_fill_octets,
|
||||
s->out_rows);
|
||||
s->out_octets = 0;
|
||||
s->out_rows = 0;
|
||||
s->flow_control_fill_octets = 0;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
void t38_non_ecm_buffer_set_mode(t38_non_ecm_buffer_state_t *s, int mode, int min_row_bits)
|
||||
{
|
||||
s->image_data_mode = mode;
|
||||
s->min_row_bits = min_row_bits;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
t38_non_ecm_buffer_state_t *t38_non_ecm_buffer_init(t38_non_ecm_buffer_state_t *s, int mode, int min_row_bits)
|
||||
{
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_terminal.c,v 1.100 2008/08/13 14:55:51 steveu Exp $
|
||||
* $Id: t38_terminal.c,v 1.101 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -192,7 +192,7 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
|
||||
&&
|
||||
(fe->current_rx_type == T30_MODEM_V21 || fe->current_rx_type == T30_MODEM_CNG))
|
||||
{
|
||||
t30_hdlc_accept(&s->t30, NULL, PUTBIT_CARRIER_DOWN, TRUE);
|
||||
t30_hdlc_accept(&s->t30, NULL, SIG_STATUS_CARRIER_DOWN, TRUE);
|
||||
}
|
||||
fe->timeout_rx_samples = 0;
|
||||
t30_front_end_status(&s->t30, T30_FRONT_END_SIGNAL_ABSENT);
|
||||
@ -357,7 +357,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK, sig end (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean");
|
||||
t30_hdlc_accept(&s->t30, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing);
|
||||
t30_hdlc_accept(&s->t30, NULL, PUTBIT_CARRIER_DOWN, TRUE);
|
||||
t30_hdlc_accept(&s->t30, NULL, SIG_STATUS_CARRIER_DOWN, TRUE);
|
||||
}
|
||||
fe->hdlc_rx.len = 0;
|
||||
fe->rx_data_missing = FALSE;
|
||||
@ -377,7 +377,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad, sig end (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean");
|
||||
t30_hdlc_accept(&s->t30, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE);
|
||||
t30_hdlc_accept(&s->t30, NULL, PUTBIT_CARRIER_DOWN, TRUE);
|
||||
t30_hdlc_accept(&s->t30, NULL, SIG_STATUS_CARRIER_DOWN, TRUE);
|
||||
}
|
||||
fe->hdlc_rx.len = 0;
|
||||
fe->rx_data_missing = FALSE;
|
||||
@ -410,7 +410,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
case T38_FIELD_T4_NON_ECM_DATA:
|
||||
if (!fe->rx_signal_present)
|
||||
{
|
||||
t30_non_ecm_put_bit(&s->t30, PUTBIT_TRAINING_SUCCEEDED);
|
||||
t30_non_ecm_put_bit(&s->t30, SIG_STATUS_TRAINING_SUCCEEDED);
|
||||
fe->rx_signal_present = TRUE;
|
||||
}
|
||||
bit_reverse(buf2, buf, len);
|
||||
@ -427,7 +427,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
|
||||
{
|
||||
if (!fe->rx_signal_present)
|
||||
{
|
||||
t30_non_ecm_put_bit(&s->t30, PUTBIT_TRAINING_SUCCEEDED);
|
||||
t30_non_ecm_put_bit(&s->t30, SIG_STATUS_TRAINING_SUCCEEDED);
|
||||
fe->rx_signal_present = TRUE;
|
||||
}
|
||||
bit_reverse(buf2, buf, len);
|
||||
|
@ -24,7 +24,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t4.c,v 1.112 2008/07/22 13:48:15 steveu Exp $
|
||||
* $Id: t4.c,v 1.113 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1963,7 +1963,7 @@ int t4_tx_get_bit(t4_state_t *s)
|
||||
int bit;
|
||||
|
||||
if (s->bit_ptr >= s->image_size)
|
||||
return PUTBIT_END_OF_DATA;
|
||||
return SIG_STATUS_END_OF_DATA;
|
||||
bit = (s->image_buffer[s->bit_ptr] >> (7 - s->bit_pos)) & 1;
|
||||
if (--s->bit_pos < 0)
|
||||
{
|
||||
@ -1999,7 +1999,7 @@ int t4_tx_check_bit(t4_state_t *s)
|
||||
int bit;
|
||||
|
||||
if (s->bit_ptr >= s->image_size)
|
||||
return PUTBIT_END_OF_DATA;
|
||||
return SIG_STATUS_END_OF_DATA;
|
||||
bit = (s->image_buffer[s->bit_ptr] >> s->bit_pos) & 1;
|
||||
return bit;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v17rx.c,v 1.112 2008/07/17 19:12:27 steveu Exp $
|
||||
* $Id: v17rx.c,v 1.116 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -471,44 +471,14 @@ static int decode_baud(v17_rx_state_t *s, complexf_t *z)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
static __inline__ void symbol_sync(v17_rx_state_t *s)
|
||||
{
|
||||
static const complexf_t cdba[4] =
|
||||
{
|
||||
{ 6.0f, 2.0f},
|
||||
{-2.0f, 6.0f},
|
||||
{ 2.0f, -6.0f},
|
||||
{-6.0f, -2.0f}
|
||||
};
|
||||
complexf_t z;
|
||||
complexf_t zz;
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
const complexi_t *target;
|
||||
#else
|
||||
const complexf_t *target;
|
||||
#endif
|
||||
int i;
|
||||
float v;
|
||||
float p;
|
||||
int bit;
|
||||
int i;
|
||||
int j;
|
||||
int32_t angle;
|
||||
int32_t ang;
|
||||
int constellation_state;
|
||||
|
||||
/* This routine processes every half a baud, as we put things into the equalizer at the T/2 rate.
|
||||
This routine adapts the position of the half baud samples, which the caller takes. */
|
||||
/* This routine adapts the position of the half baud samples entering the equalizer. */
|
||||
|
||||
/* Add a sample to the equalizer's circular buffer, but don't calculate anything
|
||||
at this time. */
|
||||
s->eq_buf[s->eq_step] = *sample;
|
||||
s->eq_step = (s->eq_step + 1) & V17_EQUALIZER_MASK;
|
||||
|
||||
/* On alternate insertions we have a whole baud and must process it. */
|
||||
if ((s->baud_half ^= 1))
|
||||
return;
|
||||
|
||||
/* Symbol timing synchronisation */
|
||||
/* Cross correlate */
|
||||
v = s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_A
|
||||
+ s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_B
|
||||
@ -532,6 +502,48 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
s->eq_put_step += i;
|
||||
s->total_baud_timing_correction += i;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
{
|
||||
static const complexf_t cdba[4] =
|
||||
{
|
||||
{ 6.0f, 2.0f},
|
||||
{-2.0f, 6.0f},
|
||||
{ 2.0f, -6.0f},
|
||||
{-6.0f, -2.0f}
|
||||
};
|
||||
complexf_t z;
|
||||
complexf_t zz;
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
const complexi_t *target;
|
||||
static const complexi16_t zero = {0, 0};
|
||||
#else
|
||||
const complexf_t *target;
|
||||
static const complexf_t zero = {0, 0};
|
||||
#endif
|
||||
float p;
|
||||
int bit;
|
||||
int i;
|
||||
int j;
|
||||
int32_t angle;
|
||||
int32_t ang;
|
||||
int constellation_state;
|
||||
|
||||
/* This routine processes every half a baud, as we put things into the equalizer at the T/2 rate. */
|
||||
|
||||
/* Add a sample to the equalizer's circular buffer, but don't calculate anything
|
||||
at this time. */
|
||||
s->eq_buf[s->eq_step] = *sample;
|
||||
s->eq_step = (s->eq_step + 1) & V17_EQUALIZER_MASK;
|
||||
|
||||
/* On alternate insertions we have a whole baud and must process it. */
|
||||
if ((s->baud_half ^= 1))
|
||||
return;
|
||||
|
||||
/* Symbol timing synchronisation */
|
||||
symbol_sync(s);
|
||||
|
||||
z = equalizer_get(s);
|
||||
|
||||
@ -545,7 +557,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
break;
|
||||
case TRAINING_STAGE_SYMBOL_ACQUISITION:
|
||||
/* Allow time for the symbol synchronisation to settle the symbol timing. */
|
||||
target = &z;
|
||||
target = &zero;
|
||||
#if defined(IAXMODEM_STUFF)
|
||||
if (++s->training_count >= 100)
|
||||
#else
|
||||
@ -562,7 +574,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
break;
|
||||
case TRAINING_STAGE_LOG_PHASE:
|
||||
/* Record the current alternate phase angle */
|
||||
target = &z;
|
||||
target = &zero;
|
||||
angle = arctan2(z.im, z.re);
|
||||
s->training_count = 1;
|
||||
if (s->short_train)
|
||||
@ -603,7 +615,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
}
|
||||
break;
|
||||
case TRAINING_STAGE_WAIT_FOR_CDBA:
|
||||
target = &z;
|
||||
target = &zero;
|
||||
angle = arctan2(z.im, z.re);
|
||||
/* Look for the initial ABAB sequence to display a phase reversal, which will
|
||||
signal the start of the scrambled CDBA segment */
|
||||
@ -665,7 +677,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
/* Park this modem */
|
||||
s->agc_scaling_save = 0.0f;
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -684,7 +696,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
descramble(s, 1);
|
||||
s->training_count = 1;
|
||||
s->training_stage = TRAINING_STAGE_COARSE_TRAIN_ON_CDBA;
|
||||
report_status_change(s, PUTBIT_TRAINING_IN_PROGRESS);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_IN_PROGRESS);
|
||||
break;
|
||||
}
|
||||
if (++s->training_count > V17_TRAINING_SEG_1_LEN)
|
||||
@ -695,7 +707,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
/* Park this modem */
|
||||
s->agc_scaling_save = 0.0f;
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
break;
|
||||
case TRAINING_STAGE_COARSE_TRAIN_ON_CDBA:
|
||||
@ -767,7 +779,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
/* Park this modem */
|
||||
s->agc_scaling_save = 0.0f;
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -806,8 +818,8 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
of a real training sequence. Note that this might be TEP. */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n");
|
||||
/* Park this modem */
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
break;
|
||||
case TRAINING_STAGE_SHORT_TRAIN_ON_CDBA_AND_TEST:
|
||||
@ -836,14 +848,14 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
{
|
||||
s->training_count = 0;
|
||||
s->training_stage = TRAINING_STAGE_TCM_WINDUP;
|
||||
report_status_change(s, PUTBIT_TRAINING_IN_PROGRESS);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_IN_PROGRESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Short training failed (convergence failed)\n");
|
||||
/* Park this modem */
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -883,7 +895,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
{
|
||||
/* We are up and running */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training succeeded (constellation mismatch %f)\n", s->training_error);
|
||||
report_status_change(s, PUTBIT_TRAINING_SUCCEEDED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_SUCCEEDED);
|
||||
/* Apply some lag to the carrier off condition, to ensure the last few bits get pushed through
|
||||
the processing. */
|
||||
s->signal_present = 60;
|
||||
@ -899,8 +911,8 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
/* Park this modem */
|
||||
if (!s->short_train)
|
||||
s->agc_scaling_save = 0.0f;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -908,7 +920,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
|
||||
default:
|
||||
/* We failed to train! */
|
||||
/* Park here until the carrier drops. */
|
||||
target = &z;
|
||||
target = &zero;
|
||||
break;
|
||||
}
|
||||
if (s->qam_report)
|
||||
@ -979,7 +991,7 @@ int v17_rx(v17_rx_state_t *s, const int16_t amp[], int len)
|
||||
/* Count down a short delay, to ensure we push the last
|
||||
few bits through the filters before stopping. */
|
||||
v17_rx_restart(s, s->bit_rate, s->short_train);
|
||||
report_status_change(s, PUTBIT_CARRIER_DOWN);
|
||||
report_status_change(s, SIG_STATUS_CARRIER_DOWN);
|
||||
continue;
|
||||
}
|
||||
#if defined(IAXMODEM_STUFF)
|
||||
@ -998,7 +1010,7 @@ int v17_rx(v17_rx_state_t *s, const int16_t amp[], int len)
|
||||
#if defined(IAXMODEM_STUFF)
|
||||
s->carrier_drop_pending = FALSE;
|
||||
#endif
|
||||
report_status_change(s, PUTBIT_CARRIER_UP);
|
||||
report_status_change(s, SIG_STATUS_CARRIER_UP);
|
||||
}
|
||||
if (s->training_stage == TRAINING_STAGE_PARKED)
|
||||
continue;
|
||||
@ -1051,20 +1063,22 @@ int v17_rx(v17_rx_state_t *s, const int16_t amp[], int len)
|
||||
for (j = 1; j < V17_RX_FILTER_STEPS; j++)
|
||||
zi.im += (int32_t) rx_pulseshaper[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.im = zi.im*s->agc_scaling;
|
||||
s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2);
|
||||
z = dds_lookup_complexf(s->carrier_phase);
|
||||
zz.re = sample.re*z.re - sample.im*z.im;
|
||||
zz.im = -sample.re*z.im - sample.im*z.re;
|
||||
process_half_baud(s, &zz);
|
||||
#else
|
||||
zz.im = rx_pulseshaper[step][0].im*s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V17_RX_FILTER_STEPS; j++)
|
||||
zz.im += rx_pulseshaper[step][j].im*s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.im = zz.im*s->agc_scaling;
|
||||
#endif
|
||||
s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2);
|
||||
/* Shift to baseband - since this is done in a full complex form, the
|
||||
result is clean, and requires no further filtering, apart from the
|
||||
equalizer. */
|
||||
z = dds_lookup_complexf(s->carrier_phase);
|
||||
zz.re = sample.re*z.re - sample.im*z.im;
|
||||
zz.im = -sample.re*z.im - sample.im*z.re;
|
||||
process_half_baud(s, &zz);
|
||||
#endif
|
||||
}
|
||||
dds_advancef(&(s->carrier_phase), s->carrier_phase_rate);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v17tx.c,v 1.62 2008/07/16 14:23:47 steveu Exp $
|
||||
* $Id: v17tx.c,v 1.64 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -222,19 +222,19 @@ static __inline__ complexf_t getbaud(v17_tx_state_t *s)
|
||||
if (s->training_step == V17_TRAINING_SHUTDOWN_END)
|
||||
{
|
||||
if (s->status_handler)
|
||||
s->status_handler(s->status_user_data, MODEM_TX_STATUS_SHUTDOWN_COMPLETE);
|
||||
s->status_handler(s->status_user_data, SIG_STATUS_SHUTDOWN_COMPLETE);
|
||||
}
|
||||
}
|
||||
}
|
||||
bits = 0;
|
||||
for (i = 0; i < s->bits_per_symbol; i++)
|
||||
{
|
||||
if ((bit = s->current_get_bit(s->get_bit_user_data)) == PUTBIT_END_OF_DATA)
|
||||
if ((bit = s->current_get_bit(s->get_bit_user_data)) == SIG_STATUS_END_OF_DATA)
|
||||
{
|
||||
/* End of real data. Switch to the fake get_bit routine, until we
|
||||
have shut down completely. */
|
||||
if (s->status_handler)
|
||||
s->status_handler(s->status_user_data, MODEM_TX_STATUS_DATA_EXHAUSTED);
|
||||
s->status_handler(s->status_user_data, SIG_STATUS_END_OF_DATA);
|
||||
s->current_get_bit = fake_get_bit;
|
||||
s->in_training = TRUE;
|
||||
bit = 1;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v22bis_rx.c,v 1.40 2008/07/25 13:56:54 steveu Exp $
|
||||
* $Id: v22bis_rx.c,v 1.41 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -607,7 +607,7 @@ int v22bis_rx(v22bis_state_t *s, const int16_t amp[], int len)
|
||||
if (power < s->rx.carrier_off_power)
|
||||
{
|
||||
v22bis_rx_restart(s, s->bit_rate);
|
||||
s->put_bit(s->user_data, PUTBIT_CARRIER_DOWN);
|
||||
s->put_bit(s->user_data, SIG_STATUS_CARRIER_DOWN);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -617,7 +617,7 @@ int v22bis_rx(v22bis_state_t *s, const int16_t amp[], int len)
|
||||
if (power < s->rx.carrier_on_power)
|
||||
continue;
|
||||
s->rx.signal_present = TRUE;
|
||||
s->put_bit(s->user_data, PUTBIT_CARRIER_UP);
|
||||
s->put_bit(s->user_data, SIG_STATUS_CARRIER_UP);
|
||||
}
|
||||
if (s->rx.training != V22BIS_TRAINING_STAGE_PARKED)
|
||||
{
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v22bis_tx.c,v 1.43 2008/07/02 14:48:26 steveu Exp $
|
||||
* $Id: v22bis_tx.c,v 1.44 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -302,7 +302,7 @@ static __inline__ int get_scrambled_bit(v22bis_state_t *s)
|
||||
{
|
||||
int bit;
|
||||
|
||||
if ((bit = s->tx.current_get_bit(s->user_data)) == PUTBIT_END_OF_DATA)
|
||||
if ((bit = s->tx.current_get_bit(s->user_data)) == SIG_STATUS_END_OF_DATA)
|
||||
{
|
||||
/* Fill out this symbol with ones, and prepare to send
|
||||
the rest of the shutdown sequence. */
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v27ter_rx.c,v 1.97 2008/08/04 14:03:17 steveu Exp $
|
||||
* $Id: v27ter_rx.c,v 1.101 2008/09/08 13:13:29 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -48,6 +48,8 @@
|
||||
#include "spandsp/complex.h"
|
||||
#include "spandsp/vector_float.h"
|
||||
#include "spandsp/complex_vector_float.h"
|
||||
#include "spandsp/vector_int.h"
|
||||
#include "spandsp/complex_vector_int.h"
|
||||
#include "spandsp/async.h"
|
||||
#include "spandsp/power_meter.h"
|
||||
#include "spandsp/arctan2.h"
|
||||
@ -72,6 +74,11 @@
|
||||
#define CARRIER_NOMINAL_FREQ 1800.0f
|
||||
#define EQUALIZER_DELTA 0.25f
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
#define FP_FACTOR 4096
|
||||
#define FP_SHIFT_FACTOR 12
|
||||
#endif
|
||||
|
||||
/* Segments of the training sequence */
|
||||
/* V.27ter defines a long and a short sequence. FAX doesn't use the
|
||||
short sequence, so it is not implemented here. */
|
||||
@ -90,17 +97,31 @@ enum
|
||||
TRAINING_STAGE_PARKED
|
||||
};
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
static const complexi16_t v27ter_constellation[8] =
|
||||
{
|
||||
{((int)(FP_FACTOR* 1.414f), ((int)(FP_FACTOR* 0.0f)}, /* 0deg */
|
||||
{((int)(FP_FACTOR* 1.0f), ((int)(FP_FACTOR* 1.0f)}, /* 45deg */
|
||||
{((int)(FP_FACTOR* 0.0f), ((int)(FP_FACTOR* 1.414f)}, /* 90deg */
|
||||
{((int)(FP_FACTOR*-1.0f), ((int)(FP_FACTOR* 1.0f)}, /* 135deg */
|
||||
{((int)(FP_FACTOR*-1.414f), ((int)(FP_FACTOR* 0.0f)}, /* 180deg */
|
||||
{((int)(FP_FACTOR*-1.0f), ((int)(FP_FACTOR*-1.0f)}, /* 225deg */
|
||||
{((int)(FP_FACTOR* 0.0f), ((int)(FP_FACTOR*-1.414f)}, /* 270deg */
|
||||
{((int)(FP_FACTOR* 1.0f), ((int)(FP_FACTOR*-1.0f)} /* 315deg */
|
||||
};
|
||||
#else
|
||||
static const complexf_t v27ter_constellation[8] =
|
||||
{
|
||||
{ 1.414f, 0.0f}, /* 0deg */
|
||||
{ 1.0f, 1.0f}, /* 45deg */
|
||||
{ 0.0f, 1.414f}, /* 90deg */
|
||||
{-1.0f, 1.0f}, /* 135deg */
|
||||
{-1.414f, 0.0f}, /* 180deg */
|
||||
{-1.0f, -1.0f}, /* 225deg */
|
||||
{ 0.0f, -1.414f}, /* 270deg */
|
||||
{ 1.0f, -1.0f} /* 315deg */
|
||||
{ 1.414f, 0.0f}, /* 0deg */
|
||||
{ 1.0f, 1.0f}, /* 45deg */
|
||||
{ 0.0f, 1.414f}, /* 90deg */
|
||||
{-1.0f, 1.0f}, /* 135deg */
|
||||
{-1.414f, 0.0f}, /* 180deg */
|
||||
{-1.0f, -1.0f}, /* 225deg */
|
||||
{ 0.0f, -1.414f}, /* 270deg */
|
||||
{ 1.0f, -1.0f} /* 315deg */
|
||||
};
|
||||
#endif
|
||||
|
||||
float v27ter_rx_carrier_frequency(v27ter_rx_state_t *s)
|
||||
{
|
||||
@ -149,14 +170,23 @@ static void report_status_change(v27ter_rx_state_t *s, int status)
|
||||
|
||||
static void equalizer_save(v27ter_rx_state_t *s)
|
||||
{
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
cvec_copyi16(s->eq_coeff_save, s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
||||
#else
|
||||
cvec_copyf(s->eq_coeff_save, s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
||||
#endif
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void equalizer_restore(v27ter_rx_state_t *s)
|
||||
{
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
||||
cvec_zeroi16(s->eq_buf, V27TER_EQUALIZER_MASK);
|
||||
#else
|
||||
cvec_copyf(s->eq_coeff, s->eq_coeff_save, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
||||
cvec_zerof(s->eq_buf, V27TER_EQUALIZER_MASK);
|
||||
#endif
|
||||
|
||||
s->eq_put_step = (s->bit_rate == 4800) ? RX_PULSESHAPER_4800_COEFF_SETS*5/2 : RX_PULSESHAPER_2400_COEFF_SETS*20/(3*2);
|
||||
s->eq_step = 0;
|
||||
@ -166,10 +196,16 @@ static void equalizer_restore(v27ter_rx_state_t *s)
|
||||
|
||||
static void equalizer_reset(v27ter_rx_state_t *s)
|
||||
{
|
||||
/* Start with an equalizer based on everything being perfect */
|
||||
/* Start with an equalizer based on everything being perfect. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
cvec_zeroi16(s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
||||
s->eq_coeff[V27TER_EQUALIZER_PRE_LEN] = complex_seti16(1.414f*FP_FACTOR, 0);
|
||||
cvec_zeroi16(s->eq_buf, V27TER_EQUALIZER_MASK);
|
||||
#else
|
||||
cvec_zerof(s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN);
|
||||
s->eq_coeff[V27TER_EQUALIZER_PRE_LEN] = complex_setf(1.414f, 0.0f);
|
||||
cvec_zerof(s->eq_buf, V27TER_EQUALIZER_MASK);
|
||||
#endif
|
||||
|
||||
s->eq_put_step = (s->bit_rate == 4800) ? RX_PULSESHAPER_4800_COEFF_SETS*5/2 : RX_PULSESHAPER_2400_COEFF_SETS*20/(3*2);
|
||||
s->eq_step = 0;
|
||||
@ -177,60 +213,122 @@ static void equalizer_reset(v27ter_rx_state_t *s)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
static __inline__ complexi16_t complex_mul_q4_12(const complexi16_t *x, const complexi16_t *y)
|
||||
{
|
||||
complexi16_t z;
|
||||
|
||||
z.re = ((int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im) >> 12;
|
||||
z.im = ((int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re) >> 12;
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
static __inline__ complexi16_t equalizer_get(v27ter_rx_state_t *s)
|
||||
#else
|
||||
static __inline__ complexf_t equalizer_get(v27ter_rx_state_t *s)
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
int p;
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
complexi16_t z;
|
||||
complexi16_t z1;
|
||||
#else
|
||||
complexf_t z;
|
||||
complexf_t z1;
|
||||
#endif
|
||||
|
||||
/* Get the next equalized value. */
|
||||
z = complex_setf(0.0f, 0.0f);
|
||||
p = s->eq_step - 1;
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
z = complex_seti16(0, 0);
|
||||
for (i = 0; i < V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN; i++)
|
||||
{
|
||||
p = (p - 1) & V27TER_EQUALIZER_MASK;
|
||||
z1 = complex_mul_q4_12(&s->eq_coeff[i], &s->eq_buf[p]);
|
||||
z = complex_addi16(&z, &z1);
|
||||
}
|
||||
#else
|
||||
z = complex_setf(0.0f, 0.0f);
|
||||
for (i = 0; i < V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN; i++)
|
||||
{
|
||||
p = (p - 1) & V27TER_EQUALIZER_MASK;
|
||||
z1 = complex_mulf(&s->eq_coeff[i], &s->eq_buf[p]);
|
||||
z = complex_addf(&z, &z1);
|
||||
}
|
||||
#endif
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
static void tune_equalizer(v27ter_rx_state_t *s, const complexi16_t *z, const complexi16_t *target)
|
||||
#else
|
||||
static void tune_equalizer(v27ter_rx_state_t *s, const complexf_t *z, const complexf_t *target)
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
int p;
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
complexi16_t ez;
|
||||
complexi16_t z1;
|
||||
#else
|
||||
complexf_t ez;
|
||||
complexf_t z1;
|
||||
#endif
|
||||
|
||||
/* Find the x and y mismatch from the exact constellation position. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
ez.re = target->re*FP_FACTOR - z->re;
|
||||
ez.im = target->im*FP_FACTOR - z->im;
|
||||
ez.re = ((int32_t) ez.re*(int32_t) s->eq_delta) >> 15;
|
||||
ez.im = ((int32_t) ez.im*(int32_t) s->eq_delta) >> 15;
|
||||
#else
|
||||
ez = complex_subf(target, z);
|
||||
ez.re *= s->eq_delta;
|
||||
ez.im *= s->eq_delta;
|
||||
#endif
|
||||
|
||||
p = s->eq_step - 1;
|
||||
for (i = 0; i < V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN; i++)
|
||||
{
|
||||
p = (p - 1) & V27TER_EQUALIZER_MASK;
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
z1 = complex_conji16(&s->eq_buf[p]);
|
||||
z1 = complex_mul_q4_12(&ez, &z1);
|
||||
s->eq_coeff[i] = complex_addi16(&s->eq_coeff[i], &z1);
|
||||
#else
|
||||
z1 = complex_conjf(&s->eq_buf[p]);
|
||||
z1 = complex_mulf(&ez, &z1);
|
||||
s->eq_coeff[i] = complex_addf(&s->eq_coeff[i], &z1);
|
||||
/* Leak a little to tame uncontrolled wandering */
|
||||
s->eq_coeff[i].re *= 0.9999f;
|
||||
s->eq_coeff[i].im *= 0.9999f;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
static __inline__ void track_carrier(v27ter_rx_state_t *s, const complexi16_t *z, const complexi16_t *target)
|
||||
#else
|
||||
static __inline__ void track_carrier(v27ter_rx_state_t *s, const complexf_t *z, const complexf_t *target)
|
||||
#endif
|
||||
{
|
||||
float error;
|
||||
|
||||
/* For small errors the imaginary part of the difference between the actual and the target
|
||||
positions is proportional to the phase error, for any particular target. However, the
|
||||
different amplitudes of the various target positions scale things. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
error = z->im*target->re - z->re*target->im;
|
||||
error /= (float) FP_FACTOR;
|
||||
#else
|
||||
error = z->im*target->re - z->re*target->im;
|
||||
#endif
|
||||
|
||||
s->carrier_phase_rate += (int32_t) (s->carrier_track_i*error);
|
||||
s->carrier_phase += (int32_t) (s->carrier_track_p*error);
|
||||
@ -295,7 +393,11 @@ static __inline__ void put_bit(v27ter_rx_state_t *s, int bit)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
static __inline__ int find_quadrant(const complexi16_t *z)
|
||||
#else
|
||||
static __inline__ int find_quadrant(const complexf_t *z)
|
||||
#endif
|
||||
{
|
||||
int b1;
|
||||
int b2;
|
||||
@ -307,7 +409,11 @@ static __inline__ int find_quadrant(const complexf_t *z)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
static __inline__ int find_octant(complexi16_t *z)
|
||||
#else
|
||||
static __inline__ int find_octant(complexf_t *z)
|
||||
#endif
|
||||
{
|
||||
float abs_re;
|
||||
float abs_im;
|
||||
@ -336,7 +442,11 @@ static __inline__ int find_octant(complexf_t *z)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
static void decode_baud(v27ter_rx_state_t *s, complexi16_t *z)
|
||||
#else
|
||||
static void decode_baud(v27ter_rx_state_t *s, complexf_t *z)
|
||||
#endif
|
||||
{
|
||||
static const uint8_t phase_steps_4800[8] =
|
||||
{
|
||||
@ -381,33 +491,12 @@ static void decode_baud(v27ter_rx_state_t *s, complexf_t *z)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t *sample)
|
||||
static __inline__ void symbol_sync(v27ter_rx_state_t *s)
|
||||
{
|
||||
static const int abab_pos[2] =
|
||||
{
|
||||
0, 4
|
||||
};
|
||||
complexf_t z;
|
||||
complexf_t zz;
|
||||
float p;
|
||||
float q;
|
||||
int i;
|
||||
int j;
|
||||
int32_t angle;
|
||||
int32_t ang;
|
||||
|
||||
/* Add a sample to the equalizer's circular buffer, but don't calculate anything
|
||||
at this time. */
|
||||
s->eq_buf[s->eq_step] = *sample;
|
||||
s->eq_step = (s->eq_step + 1) & V27TER_EQUALIZER_MASK;
|
||||
|
||||
/* On alternate insertions we have a whole baud, and must process it. */
|
||||
if ((s->baud_phase ^= 1))
|
||||
{
|
||||
//span_log(&s->logging, SPAN_LOG_FLOW, "Samp, %f, %f, %f, -1, 0x%X\n", z.re, z.im, sqrtf(z.re*z.re + z.im*z.im), s->eq_put_step);
|
||||
return;
|
||||
}
|
||||
//span_log(&s->logging, SPAN_LOG_FLOW, "Samp, %f, %f, %f, 1, 0x%X\n", z.re, z.im, sqrtf(z.re*z.re + z.im*z.im), s->eq_put_step);
|
||||
/* This routine adapts the position of the half baud samples entering the equalizer. */
|
||||
|
||||
/* Perform a Gardner test for baud alignment */
|
||||
p = s->eq_buf[(s->eq_step - 3) & V27TER_EQUALIZER_MASK].re
|
||||
@ -433,6 +522,37 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
||||
s->gardner_integrate = 0;
|
||||
}
|
||||
//span_log(&s->logging, SPAN_LOG_FLOW, "Gardner=%10.5f 0x%X\n", p, s->eq_put_step);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexi16_t *sample)
|
||||
#else
|
||||
static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t *sample)
|
||||
#endif
|
||||
{
|
||||
static const int abab_pos[2] =
|
||||
{
|
||||
0, 4
|
||||
};
|
||||
complexf_t z;
|
||||
complexf_t zz;
|
||||
float p;
|
||||
int i;
|
||||
int j;
|
||||
int32_t angle;
|
||||
int32_t ang;
|
||||
|
||||
/* Add a sample to the equalizer's circular buffer, but don't calculate anything
|
||||
at this time. */
|
||||
s->eq_buf[s->eq_step] = *sample;
|
||||
s->eq_step = (s->eq_step + 1) & V27TER_EQUALIZER_MASK;
|
||||
|
||||
/* On alternate insertions we have a whole baud, and must process it. */
|
||||
if ((s->baud_half ^= 1))
|
||||
return;
|
||||
|
||||
symbol_sync(s);
|
||||
|
||||
z = equalizer_get(s);
|
||||
|
||||
@ -498,7 +618,7 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n");
|
||||
/* Park this modem */
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -506,9 +626,20 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
||||
buffer, as well as the carrier phase, for this to play out nicely. */
|
||||
angle += 0x80000000;
|
||||
p = angle*2.0f*3.14159f/(65536.0f*65536.0f);
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
zz = complex_setf(cosf(p), -sinf(p));
|
||||
for (i = 0; i <= V27TER_EQUALIZER_MASK; i++)
|
||||
{
|
||||
z1 = complex_setf(s->eq_buf[i].re, s->eq_buf[i].im);
|
||||
z1 = complex_mulf(&z1, &zz);
|
||||
s->eq_buf[i].re = z1.re;
|
||||
s->eq_buf[i].im = z1.im;
|
||||
}
|
||||
#else
|
||||
zz = complex_setf(cosf(p), -sinf(p));
|
||||
for (i = 0; i <= V27TER_EQUALIZER_MASK; i++)
|
||||
s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz);
|
||||
#endif
|
||||
s->carrier_phase += angle;
|
||||
|
||||
s->gardner_step = 2;
|
||||
@ -519,7 +650,7 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
||||
descramble(s, 1);
|
||||
s->training_count = 1;
|
||||
s->training_stage = TRAINING_STAGE_TRAIN_ON_ABAB;
|
||||
report_status_change(s, PUTBIT_TRAINING_IN_PROGRESS);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_IN_PROGRESS);
|
||||
}
|
||||
else if (++s->training_count > V27TER_TRAINING_SEG_3_LEN)
|
||||
{
|
||||
@ -528,7 +659,7 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n");
|
||||
/* Park this modem */
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
break;
|
||||
case TRAINING_STAGE_TRAIN_ON_ABAB:
|
||||
@ -552,11 +683,22 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
||||
case TRAINING_STAGE_TEST_ONES:
|
||||
decode_baud(s, &z);
|
||||
/* Measure the training error */
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
z1.re = z.re/(float) FP_FACTOR;
|
||||
z1.im = z.im/(float) FP_FACTOR;
|
||||
if (s->bit_rate == 4800)
|
||||
zz = complex_subf(&z, &v27ter_constellation[s->constellation_state]);
|
||||
else
|
||||
zz = complex_subf(&z, &v27ter_constellation[s->constellation_state << 1]);
|
||||
zz = complex_subf(&z1, &zz);
|
||||
s->training_error += powerf(&zz);
|
||||
#else
|
||||
if (s->bit_rate == 4800)
|
||||
zz = complex_subf(&z, &v27ter_constellation[s->constellation_state]);
|
||||
else
|
||||
zz = complex_subf(&z, &v27ter_constellation[s->constellation_state << 1]);
|
||||
s->training_error += powerf(&zz);
|
||||
#endif
|
||||
if (++s->training_count >= V27TER_TRAINING_SEG_6_LEN)
|
||||
{
|
||||
if ((s->bit_rate == 4800 && s->training_error < 0.5f)
|
||||
@ -565,7 +707,7 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
||||
{
|
||||
/* We are up and running */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training succeeded (constellation mismatch %f)\n", s->training_error);
|
||||
report_status_change(s, PUTBIT_TRAINING_SUCCEEDED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_SUCCEEDED);
|
||||
/* Apply some lag to the carrier off condition, to ensure the last few bits get pushed through
|
||||
the processing. */
|
||||
s->signal_present = (s->bit_rate == 4800) ? 90 : 120;
|
||||
@ -580,7 +722,7 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (constellation mismatch %f)\n", s->training_error);
|
||||
/* Park this modem */
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -591,10 +733,21 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
|
||||
}
|
||||
if (s->qam_report)
|
||||
{
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
z1.re = z.re/(float) FP_FACTOR;
|
||||
z1.im = z.im/(float) FP_FACTOR;
|
||||
zz.re = v27ter_constellation[s->constellation_state].re;
|
||||
zz.im = v27ter_constellation[s->constellation_state].im;
|
||||
s->qam_report(s->qam_user_data,
|
||||
&z1,
|
||||
&zz,
|
||||
s->constellation_state);
|
||||
#else
|
||||
s->qam_report(s->qam_user_data,
|
||||
&z,
|
||||
&v27ter_constellation[s->constellation_state],
|
||||
s->constellation_state);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -607,10 +760,15 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
||||
int16_t x;
|
||||
int32_t diff;
|
||||
complexf_t z;
|
||||
complexf_t zz;
|
||||
complexf_t sample;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexi_t zi;
|
||||
#endif
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
complexi16_t sample;
|
||||
complexi16_t zz;
|
||||
#else
|
||||
complexf_t sample;
|
||||
complexf_t zz;
|
||||
#endif
|
||||
int32_t power;
|
||||
|
||||
@ -664,7 +822,7 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
||||
/* Count down a short delay, to ensure we push the last
|
||||
few bits through the filters before stopping. */
|
||||
v27ter_rx_restart(s, s->bit_rate, FALSE);
|
||||
report_status_change(s, PUTBIT_CARRIER_DOWN);
|
||||
report_status_change(s, SIG_STATUS_CARRIER_DOWN);
|
||||
continue;
|
||||
}
|
||||
#if defined(IAXMODEM_STUFF)
|
||||
@ -683,7 +841,7 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
||||
#if defined(IAXMODEM_STUFF)
|
||||
s->carrier_drop_pending = FALSE;
|
||||
#endif
|
||||
report_status_change(s, PUTBIT_CARRIER_UP);
|
||||
report_status_change(s, SIG_STATUS_CARRIER_UP);
|
||||
}
|
||||
/* Only spend effort processing this data if the modem is not
|
||||
parked, after training failure. */
|
||||
@ -697,7 +855,11 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
||||
if (s->training_stage == TRAINING_STAGE_SYMBOL_ACQUISITION)
|
||||
{
|
||||
/* Only AGC during the initial training */
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
s->agc_scaling = (float) FP_FACTOR*(1.0f/RX_PULSESHAPER_4800_GAIN)*1.414f/sqrtf(power);
|
||||
#else
|
||||
s->agc_scaling = (1.0f/RX_PULSESHAPER_4800_GAIN)*1.414f/sqrtf(power);
|
||||
#endif
|
||||
}
|
||||
/* Pulse shape while still at the carrier frequency, using a quadrature
|
||||
pair of filters. This results in a properly bandpass filtered complex
|
||||
@ -789,7 +951,7 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
||||
/* Count down a short delay, to ensure we push the last
|
||||
few bits through the filters before stopping. */
|
||||
v27ter_rx_restart(s, s->bit_rate, FALSE);
|
||||
report_status_change(s, PUTBIT_CARRIER_DOWN);
|
||||
report_status_change(s, SIG_STATUS_CARRIER_DOWN);
|
||||
continue;
|
||||
}
|
||||
#if defined(IAXMODEM_STUFF)
|
||||
@ -808,7 +970,7 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
||||
#if defined(IAXMODEM_STUFF)
|
||||
s->carrier_drop_pending = FALSE;
|
||||
#endif
|
||||
report_status_change(s, PUTBIT_CARRIER_UP);
|
||||
report_status_change(s, SIG_STATUS_CARRIER_UP);
|
||||
}
|
||||
/* Only spend effort processing this data if the modem is not
|
||||
parked, after training failure. */
|
||||
@ -822,7 +984,11 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len)
|
||||
if (s->training_stage == TRAINING_STAGE_SYMBOL_ACQUISITION)
|
||||
{
|
||||
/* Only AGC during the initial training */
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
s->agc_scaling = (float) FP_FACTOR*(1.0f/RX_PULSESHAPER_2400_GAIN)*1.414f/sqrtf(power);
|
||||
#else
|
||||
s->agc_scaling = (1.0f/RX_PULSESHAPER_2400_GAIN)*1.414f/sqrtf(power);
|
||||
#endif
|
||||
}
|
||||
/* Pulse shape while still at the carrier frequency, using a quadrature
|
||||
pair of filters. This results in a properly bandpass filtered complex
|
||||
@ -890,7 +1056,7 @@ int v27ter_rx_restart(v27ter_rx_state_t *s, int bit_rate, int old_train)
|
||||
s->bit_rate = bit_rate;
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
memset(s->rrc_filter, 0, sizeof(s->rrc_filter));
|
||||
vec_zeroi16(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
|
||||
#else
|
||||
vec_zerof(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
|
||||
#endif
|
||||
@ -925,7 +1091,11 @@ int v27ter_rx_restart(v27ter_rx_state_t *s, int bit_rate, int old_train)
|
||||
else
|
||||
{
|
||||
s->carrier_phase_rate = dds_phase_ratef(CARRIER_NOMINAL_FREQ);
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
s->agc_scaling = (float) FP_FACTOR*0.005f/RX_PULSESHAPER_4800_GAIN;
|
||||
#else
|
||||
s->agc_scaling = 0.005f/RX_PULSESHAPER_4800_GAIN;
|
||||
#endif
|
||||
equalizer_reset(s);
|
||||
}
|
||||
s->eq_skip = 0;
|
||||
@ -934,7 +1104,7 @@ int v27ter_rx_restart(v27ter_rx_state_t *s, int bit_rate, int old_train)
|
||||
s->gardner_integrate = 0;
|
||||
s->total_baud_timing_correction = 0;
|
||||
s->gardner_step = 512;
|
||||
s->baud_phase = 0;
|
||||
s->baud_half = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v27ter_tx.c,v 1.64 2008/07/16 14:23:47 steveu Exp $
|
||||
* $Id: v27ter_tx.c,v 1.66 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -108,12 +108,12 @@ static __inline__ int get_scrambled_bit(v27ter_tx_state_t *s)
|
||||
{
|
||||
int bit;
|
||||
|
||||
if ((bit = s->current_get_bit(s->get_bit_user_data)) == PUTBIT_END_OF_DATA)
|
||||
if ((bit = s->current_get_bit(s->get_bit_user_data)) == SIG_STATUS_END_OF_DATA)
|
||||
{
|
||||
/* End of real data. Switch to the fake get_bit routine, until we
|
||||
have shut down completely. */
|
||||
if (s->status_handler)
|
||||
s->status_handler(s->status_user_data, MODEM_TX_STATUS_DATA_EXHAUSTED);
|
||||
s->status_handler(s->status_user_data, SIG_STATUS_END_OF_DATA);
|
||||
s->current_get_bit = fake_get_bit;
|
||||
s->in_training = TRUE;
|
||||
bit = 1;
|
||||
@ -212,7 +212,7 @@ static complexf_t getbaud(v27ter_tx_state_t *s)
|
||||
if (s->training_step == V27TER_TRAINING_SHUTDOWN_END)
|
||||
{
|
||||
if (s->status_handler)
|
||||
s->status_handler(s->status_user_data, MODEM_TX_STATUS_SHUTDOWN_COMPLETE);
|
||||
s->status_handler(s->status_user_data, SIG_STATUS_SHUTDOWN_COMPLETE);
|
||||
}
|
||||
}
|
||||
/* 4800bps uses 8 phases. 2400bps uses 4 phases. */
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v29rx.c,v 1.124 2008/07/17 19:12:27 steveu Exp $
|
||||
* $Id: v29rx.c,v 1.135 2008/09/09 16:13:12 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -48,6 +48,8 @@
|
||||
#include "spandsp/complex.h"
|
||||
#include "spandsp/vector_float.h"
|
||||
#include "spandsp/complex_vector_float.h"
|
||||
#include "spandsp/vector_int.h"
|
||||
#include "spandsp/complex_vector_int.h"
|
||||
#include "spandsp/async.h"
|
||||
#include "spandsp/power_meter.h"
|
||||
#include "spandsp/arctan2.h"
|
||||
@ -67,6 +69,11 @@
|
||||
#define BAUD_RATE 2400
|
||||
#define EQUALIZER_DELTA 0.21f
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
#define FP_FACTOR 4096
|
||||
#define FP_SHIFT_FACTOR 12
|
||||
#endif
|
||||
|
||||
/* Segments of the training sequence */
|
||||
#define V29_TRAINING_SEG_2_LEN 128
|
||||
#define V29_TRAINING_SEG_3_LEN 384
|
||||
@ -109,13 +116,23 @@ static const uint8_t space_map_9600[20][20] =
|
||||
};
|
||||
|
||||
/* Coefficients for the band edge symbol timing synchroniser (alpha = 0.99) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 1.829281f /* 2*alpha*cos(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 -1.285907f /* 2*alpha*cos(high_edge) */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */
|
||||
#define SYNC_CROSS_CORR_COEFF_A -0.932131f /* -alpha^2*sin(freq_diff) */
|
||||
#define SYNC_CROSS_CORR_COEFF_B 0.752802f /* alpha*sin(high_edge) */
|
||||
#define SYNC_CROSS_CORR_COEFF_C -0.378857f /* -alpha*sin(low_edge) */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR* 1.829281f)) /* 2*alpha*cos(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*-0.980100f)) /* -alpha^2 */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR*-1.285907f)) /* 2*alpha*cos(high_edge) */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*-0.980100f)) /* -alpha^2 */
|
||||
#define SYNC_CROSS_CORR_COEFF_A ((int)(FP_FACTOR*-0.932131f)) /* -alpha^2*sin(freq_diff) */
|
||||
#define SYNC_CROSS_CORR_COEFF_B ((int)(FP_FACTOR* 0.752802f)) /* alpha*sin(high_edge) */
|
||||
#define SYNC_CROSS_CORR_COEFF_C ((int)(FP_FACTOR*-0.378857f)) /* -alpha*sin(low_edge) */
|
||||
#else
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 1.829281f /* 2*alpha*cos(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 -1.285907f /* 2*alpha*cos(high_edge) */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */
|
||||
#define SYNC_CROSS_CORR_COEFF_A -0.932131f /* -alpha^2*sin(freq_diff) */
|
||||
#define SYNC_CROSS_CORR_COEFF_B 0.752802f /* alpha*sin(high_edge) */
|
||||
#define SYNC_CROSS_CORR_COEFF_C -0.378857f /* -alpha*sin(low_edge) */
|
||||
#endif
|
||||
|
||||
float v29_rx_carrier_frequency(v29_rx_state_t *s)
|
||||
{
|
||||
@ -143,19 +160,17 @@ float v29_rx_signal_power(v29_rx_state_t *s)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
int v29_rx_equalizer_state(v29_rx_state_t *s, complexi16_t **coeffs)
|
||||
#else
|
||||
int v29_rx_equalizer_state(v29_rx_state_t *s, complexf_t **coeffs)
|
||||
#endif
|
||||
{
|
||||
*coeffs = s->eq_coeff;
|
||||
return V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void equalizer_save(v29_rx_state_t *s)
|
||||
{
|
||||
cvec_copyf(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void report_status_change(v29_rx_state_t *s, int status)
|
||||
{
|
||||
if (s->status_handler)
|
||||
@ -165,51 +180,105 @@ static void report_status_change(v29_rx_state_t *s, int status)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void equalizer_save(v29_rx_state_t *s)
|
||||
{
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
cvec_copyi16(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
#else
|
||||
cvec_copyf(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
#endif
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void equalizer_restore(v29_rx_state_t *s)
|
||||
{
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
cvec_zeroi16(s->eq_buf, V29_EQUALIZER_MASK);
|
||||
s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
#else
|
||||
cvec_copyf(s->eq_coeff, s->eq_coeff_save, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
cvec_zerof(s->eq_buf, V29_EQUALIZER_MASK);
|
||||
s->eq_delta = EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
#endif
|
||||
|
||||
s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1;
|
||||
s->eq_step = 0;
|
||||
s->eq_delta = EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void equalizer_reset(v29_rx_state_t *s)
|
||||
{
|
||||
/* Start with an equalizer based on everything being perfect */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
cvec_zeroi16(s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
s->eq_coeff[V29_EQUALIZER_PRE_LEN] = complex_seti16(3*FP_FACTOR, 0*FP_FACTOR);
|
||||
cvec_zeroi16(s->eq_buf, V29_EQUALIZER_MASK);
|
||||
s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
#else
|
||||
cvec_zerof(s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
s->eq_coeff[V29_EQUALIZER_PRE_LEN] = complex_setf(3.0f, 0.0f);
|
||||
cvec_zerof(s->eq_buf, V29_EQUALIZER_MASK);
|
||||
s->eq_delta = EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
#endif
|
||||
|
||||
s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1;
|
||||
s->eq_step = 0;
|
||||
s->eq_delta = EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static __inline__ complexi16_t complex_mul_q4_12(const complexi16_t *x, const complexi16_t *y)
|
||||
{
|
||||
complexi16_t z;
|
||||
|
||||
z.re = ((int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im) >> 12;
|
||||
z.im = ((int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re) >> 12;
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static __inline__ complexi16_t equalizer_get(v29_rx_state_t *s)
|
||||
#else
|
||||
static __inline__ complexf_t equalizer_get(v29_rx_state_t *s)
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
int p;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexi16_t z;
|
||||
complexi16_t z1;
|
||||
#else
|
||||
complexf_t z;
|
||||
complexf_t z1;
|
||||
#endif
|
||||
|
||||
/* Get the next equalized value. */
|
||||
z = complex_setf(0.0f, 0.0f);
|
||||
p = s->eq_step - 1;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
z = complex_seti16(0, 0);
|
||||
for (i = 0; i < V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; i++)
|
||||
{
|
||||
p = (p - 1) & V29_EQUALIZER_MASK;
|
||||
z1 = complex_mul_q4_12(&s->eq_coeff[i], &s->eq_buf[p]);
|
||||
z = complex_addi16(&z, &z1);
|
||||
}
|
||||
#else
|
||||
z = complex_setf(0.0f, 0.0f);
|
||||
for (i = 0; i < V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; i++)
|
||||
{
|
||||
p = (p - 1) & V29_EQUALIZER_MASK;
|
||||
z1 = complex_mulf(&s->eq_coeff[i], &s->eq_buf[p]);
|
||||
z = complex_addf(&z, &z1);
|
||||
}
|
||||
#endif
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTy)
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static void tune_equalizer(v29_rx_state_t *s, const complexi16_t *z, const complexi16_t *target)
|
||||
#else
|
||||
static void tune_equalizer(v29_rx_state_t *s, const complexf_t *z, const complexf_t *target)
|
||||
@ -217,24 +286,42 @@ static void tune_equalizer(v29_rx_state_t *s, const complexf_t *z, const complex
|
||||
{
|
||||
int i;
|
||||
int p;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexi16_t ez;
|
||||
complexi16_t z1;
|
||||
#else
|
||||
complexf_t ez;
|
||||
complexf_t z1;
|
||||
#endif
|
||||
|
||||
/* Find the x and y mismatch from the exact constellation position. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
ez.re = target->re*FP_FACTOR - z->re;
|
||||
ez.im = target->im*FP_FACTOR - z->im;
|
||||
ez.re = ((int32_t) ez.re*(int32_t) s->eq_delta) >> 15;
|
||||
ez.im = ((int32_t) ez.im*(int32_t) s->eq_delta) >> 15;
|
||||
#else
|
||||
ez = complex_subf(target, z);
|
||||
ez.re *= s->eq_delta;
|
||||
ez.im *= s->eq_delta;
|
||||
#endif
|
||||
|
||||
p = s->eq_step - 1;
|
||||
for (i = 0; i < V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; i++)
|
||||
{
|
||||
p = (p - 1) & V29_EQUALIZER_MASK;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
z1 = complex_conji16(&s->eq_buf[p]);
|
||||
z1 = complex_mul_q4_12(&ez, &z1);
|
||||
s->eq_coeff[i] = complex_addi16(&s->eq_coeff[i], &z1);
|
||||
#else
|
||||
z1 = complex_conjf(&s->eq_buf[p]);
|
||||
z1 = complex_mulf(&ez, &z1);
|
||||
s->eq_coeff[i] = complex_addf(&s->eq_coeff[i], &z1);
|
||||
/* Leak a little to tame uncontrolled wandering */
|
||||
s->eq_coeff[i].re *= 0.9999f;
|
||||
s->eq_coeff[i].im *= 0.9999f;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -253,7 +340,7 @@ static int scrambled_training_bit(v29_rx_state_t *s)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTy)
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static __inline__ int find_quadrant(const complexi16_t *z)
|
||||
#else
|
||||
static __inline__ int find_quadrant(const complexf_t *z)
|
||||
@ -269,7 +356,7 @@ static __inline__ int find_quadrant(const complexf_t *z)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTy)
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static __inline__ void track_carrier(v29_rx_state_t *s, const complexi16_t *z, const complexi16_t *target)
|
||||
#else
|
||||
static __inline__ void track_carrier(v29_rx_state_t *s, const complexf_t *z, const complexf_t *target)
|
||||
@ -290,7 +377,12 @@ static __inline__ void track_carrier(v29_rx_state_t *s, const complexf_t *z, con
|
||||
different amplitudes of the various target positions scale things. This isn't all bad,
|
||||
as the angular error for the larger amplitude constellation points is probably
|
||||
a more reliable indicator, and we are weighting it as such. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
error = z->im*target->re - z->re*target->im;
|
||||
error /= (float) FP_FACTOR;
|
||||
#else
|
||||
error = z->im*target->re - z->re*target->im;
|
||||
#endif
|
||||
|
||||
/* Use a proportional-integral approach to tracking the carrier. The PI
|
||||
parameters are coarser at first, until we get precisely on target. Then,
|
||||
@ -326,7 +418,11 @@ static __inline__ void put_bit(v29_rx_state_t *s, int bit)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static void decode_baud(v29_rx_state_t *s, complexi16_t *z)
|
||||
#else
|
||||
static void decode_baud(v29_rx_state_t *s, complexf_t *z)
|
||||
#endif
|
||||
{
|
||||
static const uint8_t phase_steps_9600[8] =
|
||||
{
|
||||
@ -342,57 +438,51 @@ static void decode_baud(v29_rx_state_t *s, complexf_t *z)
|
||||
int re;
|
||||
int im;
|
||||
|
||||
switch (s->bit_rate)
|
||||
if (s->bit_rate == 4800)
|
||||
{
|
||||
case 9600:
|
||||
default:
|
||||
/* 4800 is a special case. */
|
||||
nearest = find_quadrant(z) << 1;
|
||||
raw_bits = phase_steps_4800[((nearest - s->constellation_state) >> 1) & 3];
|
||||
put_bit(s, raw_bits);
|
||||
put_bit(s, raw_bits >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 9600 and 7200 are quite similar. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
re = (z->re + 5*FP_FACTOR) >> (FP_SHIFT_FACTOR - 1);
|
||||
im = (z->im + 5*FP_FACTOR) >> (FP_SHIFT_FACTOR - 1);
|
||||
#else
|
||||
re = (int) ((z->re + 5.0f)*2.0f);
|
||||
im = (int) ((z->im + 5.0f)*2.0f);
|
||||
#endif
|
||||
if (re > 19)
|
||||
re = 19;
|
||||
else if (re < 0)
|
||||
re = 0;
|
||||
im = (int) ((z->im + 5.0f)*2.0f);
|
||||
if (im > 19)
|
||||
im = 19;
|
||||
else if (im < 0)
|
||||
im = 0;
|
||||
nearest = space_map_9600[re][im];
|
||||
/* Deal with the amplitude bit */
|
||||
put_bit(s, nearest >> 3);
|
||||
if (s->bit_rate == 9600)
|
||||
{
|
||||
/* Send out the top (amplitude) bit. */
|
||||
put_bit(s, nearest >> 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We can reuse the space map for 9600, but drop the top bit. */
|
||||
nearest &= 7;
|
||||
}
|
||||
raw_bits = phase_steps_9600[(nearest - s->constellation_state) & 7];
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
put_bit(s, raw_bits);
|
||||
raw_bits >>= 1;
|
||||
}
|
||||
break;
|
||||
case 7200:
|
||||
/* We can reuse the space map for 9600, but drop the top bit */
|
||||
re = (int) ((z->re + 5.0f)*2.0f);
|
||||
if (re > 19)
|
||||
re = 19;
|
||||
else if (re < 0)
|
||||
re = 0;
|
||||
im = (int) ((z->im + 5.0f)*2.0f);
|
||||
if (im > 19)
|
||||
im = 19;
|
||||
else if (im < 0)
|
||||
im = 0;
|
||||
nearest = space_map_9600[re][im] & 7;
|
||||
raw_bits = phase_steps_9600[(nearest - s->constellation_state) & 7];
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
put_bit(s, raw_bits);
|
||||
raw_bits >>= 1;
|
||||
}
|
||||
break;
|
||||
case 4800:
|
||||
nearest = find_quadrant(z) << 1;
|
||||
raw_bits = phase_steps_4800[((nearest - s->constellation_state) >> 1) & 3];
|
||||
put_bit(s, raw_bits);
|
||||
put_bit(s, raw_bits >> 1);
|
||||
break;
|
||||
}
|
||||
|
||||
track_carrier(s, z, &v29_9600_constellation[nearest]);
|
||||
if (--s->eq_skip <= 0)
|
||||
{
|
||||
@ -406,7 +496,73 @@ static void decode_baud(v29_rx_state_t *s, complexf_t *z)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ void symbol_sync(v29_rx_state_t *s)
|
||||
{
|
||||
int i;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
int32_t v;
|
||||
int32_t p;
|
||||
#else
|
||||
float v;
|
||||
float p;
|
||||
#endif
|
||||
|
||||
/* This routine adapts the position of the half baud samples entering the equalizer. */
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
/* TODO: The scalings used here need more thorough evaluation, to see if overflows are possible. */
|
||||
/* Cross correlate */
|
||||
v = (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_A
|
||||
+ (((s->symbol_sync_low[0] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_B
|
||||
+ (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[0] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_C;
|
||||
/* Filter away any DC component */
|
||||
p = v - s->symbol_sync_dc_filter[1];
|
||||
s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0];
|
||||
s->symbol_sync_dc_filter[0] = v;
|
||||
/* A little integration will now filter away much of the noise */
|
||||
s->baud_phase -= p;
|
||||
if (abs(s->baud_phase) > 50*FP_FACTOR)
|
||||
{
|
||||
if (s->baud_phase > 0)
|
||||
i = (s->baud_phase > 1000*FP_FACTOR) ? 5 : 1;
|
||||
else
|
||||
i = (s->baud_phase < -1000*FP_FACTOR) ? -5 : -1;
|
||||
|
||||
//printf("v = %10.5f %5d - %f %f %d %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction);
|
||||
s->eq_put_step += i;
|
||||
s->total_baud_timing_correction += i;
|
||||
}
|
||||
#else
|
||||
/* Cross correlate */
|
||||
v = s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_A
|
||||
+ s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_B
|
||||
+ s->symbol_sync_low[1]*s->symbol_sync_high[0]*SYNC_CROSS_CORR_COEFF_C;
|
||||
/* Filter away any DC component */
|
||||
p = v - s->symbol_sync_dc_filter[1];
|
||||
s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0];
|
||||
s->symbol_sync_dc_filter[0] = v;
|
||||
/* A little integration will now filter away much of the noise */
|
||||
s->baud_phase -= p;
|
||||
if (fabsf(s->baud_phase) > 50.0f)
|
||||
{
|
||||
if (s->baud_phase > 0.0f)
|
||||
i = (s->baud_phase > 1000.0f) ? 5 : 1;
|
||||
else
|
||||
i = (s->baud_phase < -1000.0f) ? -5 : -1;
|
||||
|
||||
//printf("v = %10.5f %5d - %f %f %d %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction);
|
||||
s->eq_put_step += i;
|
||||
s->total_baud_timing_correction += i;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static void process_half_baud(v29_rx_state_t *s, complexi16_t *sample)
|
||||
#else
|
||||
static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
#endif
|
||||
{
|
||||
static const int cdcd_pos[6] =
|
||||
{
|
||||
@ -414,14 +570,17 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
0, 3,
|
||||
0, 2
|
||||
};
|
||||
complexf_t z;
|
||||
complexf_t zz;
|
||||
#if defined(SPANDSP_USE_FIXED_POINTy)
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexf_t z1;
|
||||
complexi16_t z;
|
||||
const complexi16_t *target;
|
||||
static const complexi16_t zero = {0, 0};
|
||||
#else
|
||||
complexf_t z;
|
||||
const complexf_t *target;
|
||||
static const complexf_t zero = {0.0f, 0.0f};
|
||||
#endif
|
||||
float v;
|
||||
float p;
|
||||
int bit;
|
||||
int i;
|
||||
@ -429,8 +588,7 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
int32_t angle;
|
||||
int32_t ang;
|
||||
|
||||
/* This routine processes every half a baud, as we put things into the equalizer at the T/2 rate.
|
||||
This routine adapts the position of the half baud samples, which the caller takes. */
|
||||
/* This routine processes every half a baud, as we put things into the equalizer at the T/2 rate. */
|
||||
|
||||
/* Add a sample to the equalizer's circular buffer, but don't calculate anything
|
||||
at this time. */
|
||||
@ -442,29 +600,7 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
return;
|
||||
|
||||
/* Symbol timing synchronisation */
|
||||
/* Cross correlate */
|
||||
v = s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_A
|
||||
+ s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_B
|
||||
+ s->symbol_sync_low[1]*s->symbol_sync_high[0]*SYNC_CROSS_CORR_COEFF_C;
|
||||
|
||||
/* Filter away any DC component */
|
||||
p = v - s->symbol_sync_dc_filter[1];
|
||||
s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0];
|
||||
s->symbol_sync_dc_filter[0] = v;
|
||||
/* A little integration will now filter away much of the noise */
|
||||
s->baud_phase -= p;
|
||||
|
||||
if (fabsf(s->baud_phase) > 30.0f)
|
||||
{
|
||||
if (s->baud_phase > 0.0f)
|
||||
i = (s->baud_phase > 1000.0f) ? 5 : 1;
|
||||
else
|
||||
i = (s->baud_phase < -1000.0f) ? -5 : -1;
|
||||
|
||||
//printf("v = %10.5f %5d - %f %f %d %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction);
|
||||
s->eq_put_step += i;
|
||||
s->total_baud_timing_correction += i;
|
||||
}
|
||||
symbol_sync(s);
|
||||
|
||||
z = equalizer_get(s);
|
||||
|
||||
@ -477,25 +613,27 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
break;
|
||||
case TRAINING_STAGE_SYMBOL_ACQUISITION:
|
||||
/* Allow time for symbol synchronisation to settle the symbol timing. */
|
||||
target = &z;
|
||||
target = &zero;
|
||||
if (++s->training_count >= 60)
|
||||
{
|
||||
/* Record the current phase angle */
|
||||
s->training_stage = TRAINING_STAGE_LOG_PHASE;
|
||||
s->angles[0] =
|
||||
s->start_angles[0] = arctan2(z.im, z.re);
|
||||
if (s->agc_scaling_save == 0.0f)
|
||||
s->agc_scaling_save = s->agc_scaling;
|
||||
}
|
||||
break;
|
||||
case TRAINING_STAGE_LOG_PHASE:
|
||||
/* Record the current alternate phase angle */
|
||||
target = &z;
|
||||
target = &zero;
|
||||
s->angles[1] =
|
||||
s->start_angles[1] = arctan2(z.im, z.re);
|
||||
s->training_count = 1;
|
||||
s->training_stage = TRAINING_STAGE_WAIT_FOR_CDCD;
|
||||
break;
|
||||
case TRAINING_STAGE_WAIT_FOR_CDCD:
|
||||
target = &z;
|
||||
target = &zero;
|
||||
angle = arctan2(z.im, z.re);
|
||||
/* Look for the initial ABAB sequence to display a phase reversal, which will
|
||||
signal the start of the scrambled CDCD segment */
|
||||
@ -524,24 +662,36 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
||
|
||||
s->carrier_phase_rate > dds_phase_ratef(CARRIER_NOMINAL_FREQ + 20.0f))
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n");
|
||||
/* Park this modem */
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
break;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n");
|
||||
/* Park this modem */
|
||||
s->agc_scaling_save = 0.0f;
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
break;
|
||||
}
|
||||
/* Make a step shift in the phase, to pull it into line. We need to rotate the equalizer
|
||||
buffer, as well as the carrier phase, for this to play out nicely. */
|
||||
p = angle*2.0f*3.14159f/(65536.0f*65536.0f);
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
zz = complex_setf(cosf(p), -sinf(p));
|
||||
for (i = 0; i <= V29_EQUALIZER_MASK; i++)
|
||||
{
|
||||
z1 = complex_setf(s->eq_buf[i].re, s->eq_buf[i].im);
|
||||
z1 = complex_mulf(&z1, &zz);
|
||||
s->eq_buf[i].re = z1.re;
|
||||
s->eq_buf[i].im = z1.im;
|
||||
}
|
||||
#else
|
||||
zz = complex_setf(cosf(p), -sinf(p));
|
||||
for (i = 0; i <= V29_EQUALIZER_MASK; i++)
|
||||
s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz);
|
||||
#endif
|
||||
s->carrier_phase += angle;
|
||||
/* We have just seen the first bit of the scrambled sequence, so skip it. */
|
||||
bit = scrambled_training_bit(s);
|
||||
s->training_count = 1;
|
||||
s->training_stage = TRAINING_STAGE_TRAIN_ON_CDCD;
|
||||
report_status_change(s, PUTBIT_TRAINING_IN_PROGRESS);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_IN_PROGRESS);
|
||||
break;
|
||||
}
|
||||
if (++s->training_count > V29_TRAINING_SEG_2_LEN)
|
||||
@ -550,8 +700,9 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
of a real training sequence. */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n");
|
||||
/* Park this modem */
|
||||
s->agc_scaling_save = 0.0f;
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
break;
|
||||
case TRAINING_STAGE_TRAIN_ON_CDCD:
|
||||
@ -579,8 +730,17 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
track_carrier(s, &z, target);
|
||||
tune_equalizer(s, &z, target);
|
||||
/* Measure the training error */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
z1.re = z.re/(float) FP_FACTOR;
|
||||
z1.im = z.im/(float) FP_FACTOR;
|
||||
zz.re = target->re;
|
||||
zz.im = target->im;
|
||||
zz = complex_subf(&z1, &zz);
|
||||
s->training_error += powerf(&zz);
|
||||
#else
|
||||
zz = complex_subf(&z, target);
|
||||
s->training_error += powerf(&zz);
|
||||
#endif
|
||||
if (++s->training_count >= V29_TRAINING_SEG_3_LEN)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Constellation mismatch %f\n", s->training_error);
|
||||
@ -595,8 +755,9 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (convergence failed)\n");
|
||||
/* Park this modem */
|
||||
s->agc_scaling_save = 0.0f;
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -607,15 +768,24 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
decode_baud(s, &z);
|
||||
target = &v29_9600_constellation[s->constellation_state];
|
||||
/* Measure the training error */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
z1.re = z.re/(float) FP_FACTOR;
|
||||
z1.im = z.im/(float) FP_FACTOR;
|
||||
zz.re = target->re;
|
||||
zz.im = target->im;
|
||||
zz = complex_subf(&z1, &zz);
|
||||
s->training_error += powerf(&zz);
|
||||
#else
|
||||
zz = complex_subf(&z, target);
|
||||
s->training_error += powerf(&zz);
|
||||
#endif
|
||||
if (++s->training_count >= V29_TRAINING_SEG_4_LEN)
|
||||
{
|
||||
if (s->training_error < 50.0f)
|
||||
{
|
||||
/* We are up and running */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training succeeded (constellation mismatch %f)\n", s->training_error);
|
||||
report_status_change(s, PUTBIT_TRAINING_SUCCEEDED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_SUCCEEDED);
|
||||
/* Apply some lag to the carrier off condition, to ensure the last few bits get pushed through
|
||||
the processing. */
|
||||
s->signal_present = 60;
|
||||
@ -629,8 +799,9 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
/* Training has failed */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (constellation mismatch %f)\n", s->training_error);
|
||||
/* Park this modem */
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
s->agc_scaling_save = 0.0f;
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -638,11 +809,21 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
default:
|
||||
/* We failed to train! */
|
||||
/* Park here until the carrier drops. */
|
||||
target = &z;
|
||||
target = &zero;
|
||||
break;
|
||||
}
|
||||
if (s->qam_report)
|
||||
{
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
z1.re = z.re/(float) FP_FACTOR;
|
||||
z1.im = z.im/(float) FP_FACTOR;
|
||||
zz.re = target->re;
|
||||
zz.im = target->im;
|
||||
s->qam_report(s->qam_user_data, &z1, &zz, s->constellation_state);
|
||||
#else
|
||||
s->qam_report(s->qam_user_data, &z, target, s->constellation_state);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@ -653,14 +834,19 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||
int step;
|
||||
int16_t x;
|
||||
int32_t diff;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexi16_t z;
|
||||
complexi16_t zz;
|
||||
complexi16_t sample;
|
||||
int32_t v;
|
||||
float y;
|
||||
#else
|
||||
complexf_t z;
|
||||
complexf_t zz;
|
||||
complexf_t sample;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexi_t zi;
|
||||
float v;
|
||||
#endif
|
||||
int32_t power;
|
||||
float v;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
@ -709,7 +895,7 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||
/* Count down a short delay, to ensure we push the last
|
||||
few bits through the filters before stopping. */
|
||||
v29_rx_restart(s, s->bit_rate, FALSE);
|
||||
report_status_change(s, PUTBIT_CARRIER_DOWN);
|
||||
report_status_change(s, SIG_STATUS_CARRIER_DOWN);
|
||||
continue;
|
||||
}
|
||||
#if defined(IAXMODEM_STUFF)
|
||||
@ -728,7 +914,7 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||
#if defined(IAXMODEM_STUFF)
|
||||
s->carrier_drop_pending = FALSE;
|
||||
#endif
|
||||
report_status_change(s, PUTBIT_CARRIER_UP);
|
||||
report_status_change(s, SIG_STATUS_CARRIER_UP);
|
||||
}
|
||||
if (s->training_stage == TRAINING_STAGE_PARKED)
|
||||
continue;
|
||||
@ -741,18 +927,29 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||
if (step < 0)
|
||||
step += RX_PULSESHAPER_COEFF_SETS;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
zi.re = (int32_t) rx_pulseshaper[step][0].re*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
||||
v = (int32_t) rx_pulseshaper[step][0].re*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
||||
zi.re += (int32_t) rx_pulseshaper[step][j].re*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.re = zi.re*s->agc_scaling;
|
||||
v += (int32_t) rx_pulseshaper[step][j].re*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
||||
y = v*s->agc_scaling;
|
||||
sample.re = y;
|
||||
#else
|
||||
zz.re = rx_pulseshaper[step][0].re*s->rrc_filter[s->rrc_filter_step];
|
||||
v = rx_pulseshaper[step][0].re*s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
||||
zz.re += rx_pulseshaper[step][j].re*s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.re = zz.re*s->agc_scaling;
|
||||
v += rx_pulseshaper[step][j].re*s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.re = v*s->agc_scaling;
|
||||
#endif
|
||||
|
||||
/* Symbol timing synchronisation band edge filters */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
/* Low Nyquist band edge filter */
|
||||
v = ((s->symbol_sync_low[0]*SYNC_LOW_BAND_EDGE_COEFF_0) >> 12) + ((s->symbol_sync_low[1]*SYNC_LOW_BAND_EDGE_COEFF_1) >> 12) + sample.re;
|
||||
s->symbol_sync_low[1] = s->symbol_sync_low[0];
|
||||
s->symbol_sync_low[0] = v;
|
||||
/* High Nyquist band edge filter */
|
||||
v = ((s->symbol_sync_high[0]*SYNC_HIGH_BAND_EDGE_COEFF_0) >> 12) + ((s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_1) >> 12) + sample.re;
|
||||
s->symbol_sync_high[1] = s->symbol_sync_high[0];
|
||||
s->symbol_sync_high[0] = v;
|
||||
#else
|
||||
/* Low Nyquist band edge filter */
|
||||
v = s->symbol_sync_low[0]*SYNC_LOW_BAND_EDGE_COEFF_0 + s->symbol_sync_low[1]*SYNC_LOW_BAND_EDGE_COEFF_1 + sample.re;
|
||||
s->symbol_sync_low[1] = s->symbol_sync_low[0];
|
||||
@ -761,16 +958,19 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||
v = s->symbol_sync_high[0]*SYNC_HIGH_BAND_EDGE_COEFF_0 + s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_1 + sample.re;
|
||||
s->symbol_sync_high[1] = s->symbol_sync_high[0];
|
||||
s->symbol_sync_high[0] = v;
|
||||
|
||||
#endif
|
||||
/* Put things into the equalization buffer at T/2 rate. The symbol synchronisation
|
||||
will fiddle the step to align this with the symbols. */
|
||||
if (s->eq_put_step <= 0)
|
||||
{
|
||||
if (s->training_stage == TRAINING_STAGE_SYMBOL_ACQUISITION)
|
||||
{
|
||||
/* Only AGC during the initial training */
|
||||
/* Only AGC until we have locked down the setting. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
if (s->agc_scaling_save == 0.0f)
|
||||
s->agc_scaling = (float) FP_FACTOR*(1.0f/RX_PULSESHAPER_GAIN)*5.0f*0.25f/sqrtf(power);
|
||||
#else
|
||||
if (s->agc_scaling_save == 0.0f)
|
||||
s->agc_scaling = (1.0f/RX_PULSESHAPER_GAIN)*5.0f*0.25f/sqrtf(power);
|
||||
}
|
||||
#endif
|
||||
/* Pulse shape while still at the carrier frequency, using a quadrature
|
||||
pair of filters. This results in a properly bandpass filtered complex
|
||||
signal, which can be brought directly to baseband by complex mixing.
|
||||
@ -778,24 +978,24 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||
step = -s->eq_put_step;
|
||||
if (step > RX_PULSESHAPER_COEFF_SETS - 1)
|
||||
step = RX_PULSESHAPER_COEFF_SETS - 1;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
zi.im = (int32_t) rx_pulseshaper[step][0].im*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
||||
zi.im += (int32_t) rx_pulseshaper[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.im = zi.im*s->agc_scaling;
|
||||
#else
|
||||
zz.im = rx_pulseshaper[step][0].im*s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
||||
zz.im += rx_pulseshaper[step][j].im*s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.im = zz.im*s->agc_scaling;
|
||||
#endif
|
||||
s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2);
|
||||
/* Shift to baseband - since this is done in a full complex form, the
|
||||
result is clean, and requires no further filtering, apart from the
|
||||
equalizer. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
v = (int32_t) rx_pulseshaper[step][0].im*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
||||
v += (int32_t) rx_pulseshaper[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.im = v*s->agc_scaling;
|
||||
z = dds_lookup_complexi16(s->carrier_phase);
|
||||
zz.re = ((int32_t) sample.re*(int32_t) z.re - (int32_t) sample.im*(int32_t) z.im) >> 15;
|
||||
zz.im = ((int32_t) -sample.re*(int32_t) z.im - (int32_t) sample.im*(int32_t) z.re) >> 15;
|
||||
#else
|
||||
v = rx_pulseshaper[step][0].im*s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
||||
v += rx_pulseshaper[step][j].im*s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.im = v*s->agc_scaling;
|
||||
z = dds_lookup_complexf(s->carrier_phase);
|
||||
zz.re = sample.re*z.re - sample.im*z.im;
|
||||
zz.im = -sample.re*z.im - sample.im*z.re;
|
||||
#endif
|
||||
process_half_baud(s, &zz);
|
||||
}
|
||||
dds_advancef(&(s->carrier_phase), s->carrier_phase_rate);
|
||||
@ -837,7 +1037,7 @@ int v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train)
|
||||
s->bit_rate = bit_rate;
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
memset(s->rrc_filter, 0, sizeof(s->rrc_filter));
|
||||
vec_zeroi16(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
|
||||
#else
|
||||
vec_zerof(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
|
||||
#endif
|
||||
@ -856,8 +1056,6 @@ int v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train)
|
||||
s->old_train = old_train;
|
||||
|
||||
s->carrier_phase = 0;
|
||||
s->carrier_track_i = 8000.0f;
|
||||
s->carrier_track_p = 8000000.0f;
|
||||
|
||||
power_meter_init(&(s->power), 4);
|
||||
|
||||
@ -872,13 +1070,29 @@ int v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train)
|
||||
else
|
||||
{
|
||||
s->carrier_phase_rate = dds_phase_ratef(CARRIER_NOMINAL_FREQ);
|
||||
s->agc_scaling_save = 0.0f;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
s->agc_scaling = (float) FP_FACTOR*0.0017f/RX_PULSESHAPER_GAIN;
|
||||
#else
|
||||
s->agc_scaling = 0.0017f/RX_PULSESHAPER_GAIN;
|
||||
#endif
|
||||
equalizer_reset(s);
|
||||
}
|
||||
s->eq_skip = 0;
|
||||
s->carrier_track_i = 8000.0f;
|
||||
s->carrier_track_p = 8000000.0f;
|
||||
s->last_sample = 0;
|
||||
s->eq_skip = 0;
|
||||
|
||||
/* Initialise the working data for symbol timing synchronisation */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
s->symbol_sync_low[0] = 0;
|
||||
s->symbol_sync_low[1] = 0;
|
||||
s->symbol_sync_high[0] = 0;
|
||||
s->symbol_sync_high[1] = 0;
|
||||
s->symbol_sync_dc_filter[0] = 0;
|
||||
s->symbol_sync_dc_filter[1] = 0;
|
||||
s->baud_phase = 0;
|
||||
#else
|
||||
s->symbol_sync_low[0] = 0.0f;
|
||||
s->symbol_sync_low[1] = 0.0f;
|
||||
s->symbol_sync_high[0] = 0.0f;
|
||||
@ -886,6 +1100,7 @@ int v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train)
|
||||
s->symbol_sync_dc_filter[0] = 0.0f;
|
||||
s->symbol_sync_dc_filter[1] = 0.0f;
|
||||
s->baud_phase = 0.0f;
|
||||
#endif
|
||||
s->baud_half = 0;
|
||||
|
||||
s->total_baud_timing_correction = 0;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v29tx.c,v 1.76 2008/07/16 14:23:47 steveu Exp $
|
||||
* $Id: v29tx.c,v 1.79 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -54,10 +54,6 @@
|
||||
|
||||
#include "spandsp/v29tx.h"
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
#define SPANDSP_USE_FIXED_POINTx
|
||||
#endif
|
||||
|
||||
#include "v29tx_constellation_maps.h"
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
#include "v29tx_fixed_rrc.h"
|
||||
@ -87,12 +83,12 @@ static __inline__ int get_scrambled_bit(v29_tx_state_t *s)
|
||||
int bit;
|
||||
int out_bit;
|
||||
|
||||
if ((bit = s->current_get_bit(s->get_bit_user_data)) == PUTBIT_END_OF_DATA)
|
||||
if ((bit = s->current_get_bit(s->get_bit_user_data)) == SIG_STATUS_END_OF_DATA)
|
||||
{
|
||||
/* End of real data. Switch to the fake get_bit routine, until we
|
||||
have shut down completely. */
|
||||
if (s->status_handler)
|
||||
s->status_handler(s->status_user_data, MODEM_TX_STATUS_DATA_EXHAUSTED);
|
||||
s->status_handler(s->status_user_data, SIG_STATUS_END_OF_DATA);
|
||||
s->current_get_bit = fake_get_bit;
|
||||
s->in_training = TRUE;
|
||||
bit = 1;
|
||||
@ -166,7 +162,7 @@ static __inline__ complexf_t getbaud(v29_tx_state_t *s)
|
||||
if (s->training_step == V29_TRAINING_SHUTDOWN_END)
|
||||
{
|
||||
if (s->status_handler)
|
||||
s->status_handler(s->status_user_data, MODEM_TX_STATUS_SHUTDOWN_COMPLETE);
|
||||
s->status_handler(s->status_user_data, SIG_STATUS_SHUTDOWN_COMPLETE);
|
||||
}
|
||||
}
|
||||
/* 9600bps uses the full constellation.
|
||||
|
@ -23,10 +23,10 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v29tx_constellation_maps.h,v 1.1 2008/07/10 13:34:01 steveu Exp $
|
||||
* $Id: v29tx_constellation_maps.h,v 1.2 2008/09/04 14:40:05 steveu Exp $
|
||||
*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static const complexi16_t v29_abab_constellation[6] =
|
||||
#else
|
||||
static const complexf_t v29_abab_constellation[6] =
|
||||
@ -40,7 +40,7 @@ static const complexf_t v29_abab_constellation[6] =
|
||||
{-3, 0} /* 180deg low */
|
||||
};
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static const complexi16_t v29_cdcd_constellation[6] =
|
||||
#else
|
||||
static const complexf_t v29_cdcd_constellation[6] =
|
||||
@ -54,7 +54,7 @@ static const complexf_t v29_cdcd_constellation[6] =
|
||||
{ 0, 3} /* 90deg low */
|
||||
};
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static const complexi16_t v29_9600_constellation[16] =
|
||||
#else
|
||||
static const complexf_t v29_9600_constellation[16] =
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v42.c,v 1.42 2008/05/13 13:17:25 steveu Exp $
|
||||
* $Id: v42.c,v 1.43 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/* THIS IS A WORK IN PROGRESS. IT IS NOT FINISHED. */
|
||||
@ -721,31 +721,7 @@ fprintf(stderr, "LAPM receive %d %d\n", ok, len);
|
||||
if (len < 0)
|
||||
{
|
||||
/* Special conditions */
|
||||
switch (len)
|
||||
{
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
span_log(&s->logging, SPAN_LOG_DEBUG, "Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
span_log(&s->logging, SPAN_LOG_DEBUG, "Training succeeded\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
span_log(&s->logging, SPAN_LOG_DEBUG, "Carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
span_log(&s->logging, SPAN_LOG_DEBUG, "Carrier down\n");
|
||||
break;
|
||||
case PUTBIT_FRAMING_OK:
|
||||
span_log(&s->logging, SPAN_LOG_DEBUG, "Framing OK\n");
|
||||
break;
|
||||
case PUTBIT_ABORT:
|
||||
span_log(&s->logging, SPAN_LOG_DEBUG, "Abort\n");
|
||||
break;
|
||||
default:
|
||||
span_log(&s->logging, SPAN_LOG_DEBUG, "Eh!\n");
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
span_log(&s->logging, SPAN_LOG_DEBUG, "V.42 rx status is %s (%d)\n", signal_status_to_str(len), len);
|
||||
return;
|
||||
}
|
||||
/*endif*/
|
||||
@ -1133,19 +1109,7 @@ static void negotiation_rx_bit(v42_state_t *s, int new_bit)
|
||||
if (new_bit < 0)
|
||||
{
|
||||
/* Special conditions */
|
||||
switch (new_bit)
|
||||
{
|
||||
case PUTBIT_CARRIER_UP:
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
break;
|
||||
default:
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "Unexpected special 'bit' code %d\n", new_bit);
|
||||
break;
|
||||
}
|
||||
/*endswitch*/
|
||||
span_log(&s->logging, SPAN_LOG_DEBUG, "V.42 rx status is %s (%d)\n", signal_status_to_str(new_bit), new_bit);
|
||||
return;
|
||||
}
|
||||
/*endif*/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v8.c,v 1.30 2008/07/02 14:48:26 steveu Exp $
|
||||
* $Id: v8.c,v 1.31 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -396,10 +396,10 @@ static void put_bit(void *user_data, int bit)
|
||||
/* Special conditions */
|
||||
switch (bit)
|
||||
{
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: vector_int.c,v 1.11 2008/07/02 14:48:26 steveu Exp $
|
||||
* $Id: vector_int.c,v 1.12 2008/09/01 16:07:34 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -87,7 +87,7 @@ int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n)
|
||||
|
||||
" .p2align 2;\n"
|
||||
"1:\n"
|
||||
" addl $24,%%edx;\n" /* now edx = top - 8 */
|
||||
" addl $24,%%edx;\n" /* Now edx = top - 8 */
|
||||
" cmpl %%edx,%%esi;\n"
|
||||
" ja 3f;\n"
|
||||
|
||||
@ -106,7 +106,7 @@ int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n)
|
||||
|
||||
" .p2align 2;\n"
|
||||
"3:\n"
|
||||
" addl $4,%%edx;\n" /* now edx = top - 4 */
|
||||
" addl $4,%%edx;\n" /* Now edx = top - 4 */
|
||||
" cmpl %%edx,%%esi;\n"
|
||||
" ja 5f;\n"
|
||||
|
||||
@ -121,7 +121,7 @@ int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n)
|
||||
|
||||
" .p2align 2;\n"
|
||||
"5:\n"
|
||||
" addl $2,%%edx;\n" /* now edx = top - 2 */
|
||||
" addl $2,%%edx;\n" /* Now edx = top - 2 */
|
||||
" cmpl %%edx,%%esi;\n"
|
||||
" ja 6f;\n"
|
||||
|
||||
@ -141,7 +141,7 @@ int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n)
|
||||
" movq %%mm0,%%mm1;\n"
|
||||
" punpckhdq %%mm0,%%mm1;\n"
|
||||
" paddd %%mm1,%%mm0;\n"
|
||||
/* et voila, eax has the final result */
|
||||
/* Et voila, eax has the final result */
|
||||
" movd %%mm0,%%eax;\n"
|
||||
|
||||
" emms;\n"
|
||||
|
@ -16,7 +16,7 @@
|
||||
## along with this program; if not, write to the Free Software
|
||||
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
##
|
||||
## $Id: Makefile.am,v 1.105 2008/08/16 15:45:45 steveu Exp $
|
||||
## $Id: Makefile.am,v 1.106 2008/09/09 14:05:55 steveu Exp $
|
||||
|
||||
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
|
||||
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
|
||||
@ -274,7 +274,7 @@ tone_generate_tests_SOURCES = tone_generate_tests.c
|
||||
tone_generate_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp
|
||||
|
||||
tsb85_tests_SOURCES = tsb85_tests.c fax_tester.c
|
||||
tsb85_tests_LDADD = $(LIBDIR) -lspandsp
|
||||
tsb85_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp
|
||||
|
||||
v17_tests_SOURCES = v17_tests.c line_model_monitor.cpp modem_monitor.cpp
|
||||
v17_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: bert_tests.c,v 1.24 2008/05/13 13:17:25 steveu Exp $
|
||||
* $Id: bert_tests.c,v 1.25 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -423,7 +423,7 @@ int main(int argc, char *argv[])
|
||||
bert_set_report(&bert, 100000, reporter, (intptr_t) 0);
|
||||
for (;;)
|
||||
{
|
||||
if ((bit = bert_get_bit(&bert)) == PUTBIT_END_OF_DATA)
|
||||
if ((bit = bert_get_bit(&bert)) == SIG_STATUS_END_OF_DATA)
|
||||
{
|
||||
bert_result(&bert, &bert_results);
|
||||
printf("Rate test: %d bits, %d bad bits, %d resyncs\n", bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: echo_monitor.cpp,v 1.12 2008/05/27 15:08:21 steveu Exp $
|
||||
* $Id: echo_monitor.cpp,v 1.13 2008/09/08 16:10:41 steveu Exp $
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -56,44 +56,49 @@
|
||||
#include "spandsp.h"
|
||||
#include "echo_monitor.h"
|
||||
|
||||
Fl_Double_Window *w;
|
||||
struct line_model_monitor_s
|
||||
{
|
||||
Fl_Double_Window *w;
|
||||
|
||||
Fl_Audio_Meter *audio_meter;
|
||||
Fl_Audio_Meter *audio_meter;
|
||||
Fl_Group *c_spec;
|
||||
Fl_Group *c_right;
|
||||
Fl_Group *c_can;
|
||||
Fl_Group *c_line_model;
|
||||
|
||||
Fl_Group *c_spec;
|
||||
Fl_Group *c_right;
|
||||
Fl_Group *c_can;
|
||||
Fl_Group *c_line_model;
|
||||
Ca_Canvas *canvas_spec;
|
||||
Ca_X_Axis *spec_freq;
|
||||
Ca_Y_Axis *spec_amp;
|
||||
Ca_Line *spec_re;
|
||||
double spec_re_plot[2*512];
|
||||
|
||||
Ca_Canvas *canvas_spec;
|
||||
Ca_X_Axis *spec_freq;
|
||||
Ca_Y_Axis *spec_amp;
|
||||
Ca_Line *spec_re = NULL;
|
||||
double spec_re_plot[2*512];
|
||||
Ca_Canvas *canvas_can;
|
||||
Ca_X_Axis *can_x;
|
||||
Ca_Y_Axis *can_y;
|
||||
Ca_Line *can_re;
|
||||
double can_re_plot[512];
|
||||
|
||||
Ca_Canvas *canvas_can;
|
||||
Ca_X_Axis *can_x;
|
||||
Ca_Y_Axis *can_y;
|
||||
Ca_Line *can_re = NULL;
|
||||
double can_re_plot[512];
|
||||
Ca_Canvas *canvas_line_model;
|
||||
Ca_X_Axis *line_model_x;
|
||||
Ca_Y_Axis *line_model_y;
|
||||
Ca_Line *line_model_re;
|
||||
double line_model_re_plot[512];
|
||||
|
||||
int in_ptr;
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
double in[1024][2];
|
||||
double out[1024][2];
|
||||
#else
|
||||
fftw_complex in[1024];
|
||||
fftw_complex out[1024];
|
||||
#endif
|
||||
fftw_plan p;
|
||||
};
|
||||
|
||||
Ca_Canvas *canvas_line_model;
|
||||
Ca_X_Axis *line_model_x;
|
||||
Ca_Y_Axis *line_model_y;
|
||||
Ca_Line *line_model_re = NULL;
|
||||
double line_model_re_plot[512];
|
||||
|
||||
static int skip = 0;
|
||||
|
||||
int in_ptr;
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
double in[1024][2];
|
||||
double out[1024][2];
|
||||
#else
|
||||
fftw_complex in[1024];
|
||||
fftw_complex out[1024];
|
||||
#endif
|
||||
fftw_plan p;
|
||||
static struct line_model_monitor_s echo;
|
||||
static struct line_model_monitor_s *s = &echo;
|
||||
|
||||
int echo_can_monitor_can_update(const int16_t *coeffs, int len)
|
||||
{
|
||||
@ -101,25 +106,25 @@ int echo_can_monitor_can_update(const int16_t *coeffs, int len)
|
||||
float min;
|
||||
float max;
|
||||
|
||||
if (can_re)
|
||||
delete can_re;
|
||||
if (s->can_re)
|
||||
delete s->can_re;
|
||||
|
||||
canvas_can->current(canvas_can);
|
||||
s->canvas_can->current(s->canvas_can);
|
||||
i = 0;
|
||||
min = coeffs[i];
|
||||
max = coeffs[i];
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
can_re_plot[2*i] = i;
|
||||
can_re_plot[2*i + 1] = coeffs[i];
|
||||
s->can_re_plot[2*i] = i;
|
||||
s->can_re_plot[2*i + 1] = coeffs[i];
|
||||
if (min > coeffs[i])
|
||||
min = coeffs[i];
|
||||
if (max < coeffs[i])
|
||||
max = coeffs[i];
|
||||
}
|
||||
can_y->maximum((max == min) ? max + 0.2 : max);
|
||||
can_y->minimum(min);
|
||||
can_re = new Ca_Line(len, can_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
s->can_y->maximum((max == min) ? max + 0.2 : max);
|
||||
s->can_y->minimum(min);
|
||||
s->can_re = new Ca_Line(len, s->can_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
if (++skip >= 100)
|
||||
{
|
||||
skip = 0;
|
||||
@ -135,25 +140,25 @@ int echo_can_monitor_line_model_update(const int32_t *coeffs, int len)
|
||||
float min;
|
||||
float max;
|
||||
|
||||
if (line_model_re)
|
||||
delete line_model_re;
|
||||
if (s->line_model_re)
|
||||
delete s->line_model_re;
|
||||
|
||||
canvas_line_model->current(canvas_line_model);
|
||||
s->canvas_line_model->current(s->canvas_line_model);
|
||||
i = 0;
|
||||
min = coeffs[i];
|
||||
max = coeffs[i];
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
line_model_re_plot[2*i] = i;
|
||||
line_model_re_plot[2*i + 1] = coeffs[i];
|
||||
s->line_model_re_plot[2*i] = i;
|
||||
s->line_model_re_plot[2*i + 1] = coeffs[i];
|
||||
if (min > coeffs[i])
|
||||
min = coeffs[i];
|
||||
if (max < coeffs[i])
|
||||
max = coeffs[i];
|
||||
}
|
||||
line_model_y->maximum((max == min) ? max + 0.2 : max);
|
||||
line_model_y->minimum(min);
|
||||
line_model_re = new Ca_Line(len, line_model_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
s->line_model_y->maximum((max == min) ? max + 0.2 : max);
|
||||
s->line_model_y->minimum(min);
|
||||
s->line_model_re = new Ca_Line(len, s->line_model_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
if (++skip >= 100)
|
||||
{
|
||||
skip = 0;
|
||||
@ -169,18 +174,18 @@ int echo_can_monitor_line_spectrum_update(const int16_t amp[], int len)
|
||||
int x;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
audio_meter->sample(amp[i]/32768.0);
|
||||
s->audio_meter->sample(amp[i]/32768.0);
|
||||
|
||||
if (in_ptr + len < 512)
|
||||
if (s->in_ptr + len < 512)
|
||||
{
|
||||
/* Just add this fragment to the buffer. */
|
||||
for (i = 0; i < len; i++)
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
in[in_ptr + i][0] = amp[i];
|
||||
s->in[s->in_ptr + i][0] = amp[i];
|
||||
#else
|
||||
in[in_ptr + i].re = amp[i];
|
||||
s->in[s->in_ptr + i].re = amp[i];
|
||||
#endif
|
||||
in_ptr += len;
|
||||
s->in_ptr += len;
|
||||
return 0;
|
||||
}
|
||||
if (len >= 512)
|
||||
@ -190,9 +195,9 @@ int echo_can_monitor_line_spectrum_update(const int16_t amp[], int len)
|
||||
x = len - 512;
|
||||
for (i = 0; i < 512; i++)
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
in[i][0] = amp[x + i];
|
||||
s->in[i][0] = amp[x + i];
|
||||
#else
|
||||
in[i].re = amp[x + i];
|
||||
s->in[i].re = amp[x + i];
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -201,36 +206,36 @@ int echo_can_monitor_line_spectrum_update(const int16_t amp[], int len)
|
||||
x = 512 - len;
|
||||
for (i = 0; i < x; i++)
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
in[i][0] = in[in_ptr - x + i][0];
|
||||
s->in[i][0] = s->in[s->in_ptr - x + i][0];
|
||||
#else
|
||||
in[i].re = in[in_ptr - x + i].re;
|
||||
s->in[i].re = s->in[s->in_ptr - x + i].re;
|
||||
#endif
|
||||
for (i = x; i < 512; i++)
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
in[i][0] = amp[i - x];
|
||||
s->in[i][0] = amp[i - x];
|
||||
#else
|
||||
in[i].re = amp[i - x];
|
||||
s->in[i].re = amp[i - x];
|
||||
#endif
|
||||
}
|
||||
in_ptr = 0;
|
||||
s->in_ptr = 0;
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
fftw_execute(p);
|
||||
fftw_execute(s->p);
|
||||
#else
|
||||
fftw_one(p, in, out);
|
||||
fftw_one(s->p, s->in, s->out);
|
||||
#endif
|
||||
if (spec_re)
|
||||
delete spec_re;
|
||||
canvas_spec->current(canvas_spec);
|
||||
if (s->spec_re)
|
||||
delete s->spec_re;
|
||||
s->canvas_spec->current(s->canvas_spec);
|
||||
for (i = 0; i < 512; i++)
|
||||
{
|
||||
spec_re_plot[2*i] = i*4000.0/512.0;
|
||||
s->spec_re_plot[2*i] = i*4000.0/512.0;
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
spec_re_plot[2*i + 1] = 20.0*log10(sqrt(out[i][0]*out[i][0] + out[i][1]*out[i][1])/(256.0*32768)) + 3.14;
|
||||
s->spec_re_plot[2*i + 1] = 20.0*log10(sqrt(s->out[i][0]*s->out[i][0] + s->out[i][1]*s->out[i][1])/(256.0*32768)) + 3.14;
|
||||
#else
|
||||
spec_re_plot[2*i + 1] = 20.0*log10(sqrt(out[i].re*out[i].re + out[i].im*out[i].im)/(256.0*32768)) + 3.14;
|
||||
s->spec_re_plot[2*i + 1] = 20.0*log10(sqrt(s->out[i].re*s->out[i].re + s->out[i].im*s->out[i].im)/(256.0*32768)) + 3.14;
|
||||
#endif
|
||||
}
|
||||
spec_re = new Ca_Line(512, spec_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
s->spec_re = new Ca_Line(512, s->spec_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
Fl::check();
|
||||
return 0;
|
||||
}
|
||||
@ -243,167 +248,170 @@ int start_echo_can_monitor(int len)
|
||||
float y;
|
||||
int i;
|
||||
|
||||
w = new Fl_Double_Window(850, 400, "Echo canceller monitor");
|
||||
s->w = new Fl_Double_Window(850, 400, "Echo canceller monitor");
|
||||
|
||||
c_spec = new Fl_Group(0, 0, 380, 400);
|
||||
c_spec->box(FL_DOWN_BOX);
|
||||
c_spec->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
s->c_spec = new Fl_Group(0, 0, 380, 400);
|
||||
s->c_spec->box(FL_DOWN_BOX);
|
||||
s->c_spec->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
|
||||
canvas_spec = new Ca_Canvas(60, 30, 300, 300, "Spectrum");
|
||||
canvas_spec->box(FL_PLASTIC_DOWN_BOX);
|
||||
canvas_spec->color(7);
|
||||
canvas_spec->align(FL_ALIGN_TOP);
|
||||
canvas_spec->border(15);
|
||||
s->canvas_spec = new Ca_Canvas(60, 30, 300, 300, "Spectrum");
|
||||
s->canvas_spec->box(FL_PLASTIC_DOWN_BOX);
|
||||
s->canvas_spec->color(7);
|
||||
s->canvas_spec->align(FL_ALIGN_TOP);
|
||||
s->canvas_spec->border(15);
|
||||
|
||||
spec_freq = new Ca_X_Axis(65, 330, 290, 30, "Freq (Hz)");
|
||||
spec_freq->align(FL_ALIGN_BOTTOM);
|
||||
spec_freq->minimum(0);
|
||||
spec_freq->maximum(4000);
|
||||
spec_freq->label_format("%g");
|
||||
spec_freq->minor_grid_color(fl_gray_ramp(20));
|
||||
spec_freq->major_grid_color(fl_gray_ramp(15));
|
||||
spec_freq->label_grid_color(fl_gray_ramp(10));
|
||||
spec_freq->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
spec_freq->minor_grid_style(FL_DOT);
|
||||
spec_freq->major_step(5);
|
||||
spec_freq->label_step(1);
|
||||
spec_freq->axis_color(FL_BLACK);
|
||||
spec_freq->axis_align(CA_BOTTOM | CA_LINE);
|
||||
s->spec_freq = new Ca_X_Axis(65, 330, 290, 30, "Freq (Hz)");
|
||||
s->spec_freq->align(FL_ALIGN_BOTTOM);
|
||||
s->spec_freq->minimum(0);
|
||||
s->spec_freq->maximum(4000);
|
||||
s->spec_freq->label_format("%g");
|
||||
s->spec_freq->minor_grid_color(fl_gray_ramp(20));
|
||||
s->spec_freq->major_grid_color(fl_gray_ramp(15));
|
||||
s->spec_freq->label_grid_color(fl_gray_ramp(10));
|
||||
s->spec_freq->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->spec_freq->minor_grid_style(FL_DOT);
|
||||
s->spec_freq->major_step(5);
|
||||
s->spec_freq->label_step(1);
|
||||
s->spec_freq->axis_color(FL_BLACK);
|
||||
s->spec_freq->axis_align(CA_BOTTOM | CA_LINE);
|
||||
|
||||
spec_amp = new Ca_Y_Axis(20, 35, 40, 290, "Amp (dBmO)");
|
||||
spec_amp->align(FL_ALIGN_LEFT);
|
||||
spec_amp->minimum(-80.0);
|
||||
spec_amp->maximum(10.0);
|
||||
spec_amp->minor_grid_color(fl_gray_ramp(20));
|
||||
spec_amp->major_grid_color(fl_gray_ramp(15));
|
||||
spec_amp->label_grid_color(fl_gray_ramp(10));
|
||||
//spec_amp->grid_visible(CA_MINOR_TICK | CA_MAJOR_TICK | CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
spec_amp->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
spec_amp->minor_grid_style(FL_DOT);
|
||||
spec_amp->major_step(5);
|
||||
spec_amp->label_step(1);
|
||||
spec_amp->axis_color(FL_BLACK);
|
||||
s->spec_amp = new Ca_Y_Axis(20, 35, 40, 290, "Amp (dBmO)");
|
||||
s->spec_amp->align(FL_ALIGN_LEFT);
|
||||
s->spec_amp->minimum(-80.0);
|
||||
s->spec_amp->maximum(10.0);
|
||||
s->spec_amp->minor_grid_color(fl_gray_ramp(20));
|
||||
s->spec_amp->major_grid_color(fl_gray_ramp(15));
|
||||
s->spec_amp->label_grid_color(fl_gray_ramp(10));
|
||||
//s->spec_amp->grid_visible(CA_MINOR_TICK | CA_MAJOR_TICK | CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->spec_amp->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->spec_amp->minor_grid_style(FL_DOT);
|
||||
s->spec_amp->major_step(5);
|
||||
s->spec_amp->label_step(1);
|
||||
s->spec_amp->axis_color(FL_BLACK);
|
||||
|
||||
spec_amp->current();
|
||||
s->spec_amp->current();
|
||||
s->spec_re = NULL;
|
||||
|
||||
c_spec->end();
|
||||
s->c_spec->end();
|
||||
|
||||
c_right = new Fl_Group(440, 0, 465, 405);
|
||||
s->c_right = new Fl_Group(440, 0, 465, 405);
|
||||
|
||||
c_can = new Fl_Group(380, 0, 415, 200);
|
||||
c_can->box(FL_DOWN_BOX);
|
||||
c_can->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
c_can->current();
|
||||
s->c_can = new Fl_Group(380, 0, 415, 200);
|
||||
s->c_can->box(FL_DOWN_BOX);
|
||||
s->c_can->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
s->c_can->current();
|
||||
|
||||
canvas_can = new Ca_Canvas(460, 35, 300, 100, "Canceller coefficients");
|
||||
canvas_can->box(FL_PLASTIC_DOWN_BOX);
|
||||
canvas_can->color(7);
|
||||
canvas_can->align(FL_ALIGN_TOP);
|
||||
Fl_Group::current()->resizable(canvas_can);
|
||||
canvas_can->border(15);
|
||||
s->canvas_can = new Ca_Canvas(460, 35, 300, 100, "Canceller coefficients");
|
||||
s->canvas_can->box(FL_PLASTIC_DOWN_BOX);
|
||||
s->canvas_can->color(7);
|
||||
s->canvas_can->align(FL_ALIGN_TOP);
|
||||
Fl_Group::current()->resizable(s->canvas_can);
|
||||
s->canvas_can->border(15);
|
||||
|
||||
can_x = new Ca_X_Axis(465, 135, 290, 30, "Tap");
|
||||
can_x->align(FL_ALIGN_BOTTOM);
|
||||
can_x->minimum(0.0);
|
||||
can_x->maximum((float) len);
|
||||
can_x->label_format("%g");
|
||||
can_x->minor_grid_color(fl_gray_ramp(20));
|
||||
can_x->major_grid_color(fl_gray_ramp(15));
|
||||
can_x->label_grid_color(fl_gray_ramp(10));
|
||||
can_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
can_x->minor_grid_style(FL_DOT);
|
||||
can_x->major_step(5);
|
||||
can_x->label_step(1);
|
||||
can_x->axis_align(CA_BOTTOM | CA_LINE);
|
||||
can_x->axis_color(FL_BLACK);
|
||||
can_x->current();
|
||||
s->can_x = new Ca_X_Axis(465, 135, 290, 30, "Tap");
|
||||
s->can_x->align(FL_ALIGN_BOTTOM);
|
||||
s->can_x->minimum(0.0);
|
||||
s->can_x->maximum((float) len);
|
||||
s->can_x->label_format("%g");
|
||||
s->can_x->minor_grid_color(fl_gray_ramp(20));
|
||||
s->can_x->major_grid_color(fl_gray_ramp(15));
|
||||
s->can_x->label_grid_color(fl_gray_ramp(10));
|
||||
s->can_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->can_x->minor_grid_style(FL_DOT);
|
||||
s->can_x->major_step(5);
|
||||
s->can_x->label_step(1);
|
||||
s->can_x->axis_align(CA_BOTTOM | CA_LINE);
|
||||
s->can_x->axis_color(FL_BLACK);
|
||||
s->can_x->current();
|
||||
|
||||
can_y = new Ca_Y_Axis(420, 40, 40, 90, "Amp");
|
||||
can_y->align(FL_ALIGN_LEFT);
|
||||
can_y->minimum(-0.1);
|
||||
can_y->maximum(0.1);
|
||||
can_y->minor_grid_color(fl_gray_ramp(20));
|
||||
can_y->major_grid_color(fl_gray_ramp(15));
|
||||
can_y->label_grid_color(fl_gray_ramp(10));
|
||||
can_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
can_y->minor_grid_style(FL_DOT);
|
||||
can_y->major_step(5);
|
||||
can_y->label_step(1);
|
||||
can_y->axis_color(FL_BLACK);
|
||||
can_y->current();
|
||||
s->can_y = new Ca_Y_Axis(420, 40, 40, 90, "Amp");
|
||||
s->can_y->align(FL_ALIGN_LEFT);
|
||||
s->can_y->minimum(-0.1);
|
||||
s->can_y->maximum(0.1);
|
||||
s->can_y->minor_grid_color(fl_gray_ramp(20));
|
||||
s->can_y->major_grid_color(fl_gray_ramp(15));
|
||||
s->can_y->label_grid_color(fl_gray_ramp(10));
|
||||
s->can_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->can_y->minor_grid_style(FL_DOT);
|
||||
s->can_y->major_step(5);
|
||||
s->can_y->label_step(1);
|
||||
s->can_y->axis_color(FL_BLACK);
|
||||
s->can_y->current();
|
||||
|
||||
c_can->end();
|
||||
s->c_can->end();
|
||||
s->can_re = NULL;
|
||||
|
||||
c_line_model = new Fl_Group(380, 200, 415, 200);
|
||||
c_line_model->box(FL_DOWN_BOX);
|
||||
c_line_model->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
c_line_model->current();
|
||||
s->c_line_model = new Fl_Group(380, 200, 415, 200);
|
||||
s->c_line_model->box(FL_DOWN_BOX);
|
||||
s->c_line_model->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
s->c_line_model->current();
|
||||
|
||||
canvas_line_model = new Ca_Canvas(460, 235, 300, 100, "Line impulse response model");
|
||||
canvas_line_model->box(FL_PLASTIC_DOWN_BOX);
|
||||
canvas_line_model->color(7);
|
||||
canvas_line_model->align(FL_ALIGN_TOP);
|
||||
Fl_Group::current()->resizable(canvas_line_model);
|
||||
canvas_line_model->border(15);
|
||||
s->canvas_line_model = new Ca_Canvas(460, 235, 300, 100, "Line impulse response model");
|
||||
s->canvas_line_model->box(FL_PLASTIC_DOWN_BOX);
|
||||
s->canvas_line_model->color(7);
|
||||
s->canvas_line_model->align(FL_ALIGN_TOP);
|
||||
Fl_Group::current()->resizable(s->canvas_line_model);
|
||||
s->canvas_line_model->border(15);
|
||||
|
||||
line_model_x = new Ca_X_Axis(465, 335, 290, 30, "Tap");
|
||||
line_model_x->align(FL_ALIGN_BOTTOM);
|
||||
line_model_x->minimum(0.0);
|
||||
line_model_x->maximum((float) len);
|
||||
line_model_x->label_format("%g");
|
||||
line_model_x->minor_grid_color(fl_gray_ramp(20));
|
||||
line_model_x->major_grid_color(fl_gray_ramp(15));
|
||||
line_model_x->label_grid_color(fl_gray_ramp(10));
|
||||
line_model_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
line_model_x->minor_grid_style(FL_DOT);
|
||||
line_model_x->major_step(5);
|
||||
line_model_x->label_step(1);
|
||||
line_model_x->axis_align(CA_BOTTOM | CA_LINE);
|
||||
line_model_x->axis_color(FL_BLACK);
|
||||
line_model_x->current();
|
||||
s->line_model_x = new Ca_X_Axis(465, 335, 290, 30, "Tap");
|
||||
s->line_model_x->align(FL_ALIGN_BOTTOM);
|
||||
s->line_model_x->minimum(0.0);
|
||||
s->line_model_x->maximum((float) len);
|
||||
s->line_model_x->label_format("%g");
|
||||
s->line_model_x->minor_grid_color(fl_gray_ramp(20));
|
||||
s->line_model_x->major_grid_color(fl_gray_ramp(15));
|
||||
s->line_model_x->label_grid_color(fl_gray_ramp(10));
|
||||
s->line_model_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->line_model_x->minor_grid_style(FL_DOT);
|
||||
s->line_model_x->major_step(5);
|
||||
s->line_model_x->label_step(1);
|
||||
s->line_model_x->axis_align(CA_BOTTOM | CA_LINE);
|
||||
s->line_model_x->axis_color(FL_BLACK);
|
||||
s->line_model_x->current();
|
||||
|
||||
line_model_y = new Ca_Y_Axis(420, 240, 40, 90, "Amp");
|
||||
line_model_y->align(FL_ALIGN_LEFT);
|
||||
line_model_y->minimum(-0.1);
|
||||
line_model_y->maximum(0.1);
|
||||
line_model_y->minor_grid_color(fl_gray_ramp(20));
|
||||
line_model_y->major_grid_color(fl_gray_ramp(15));
|
||||
line_model_y->label_grid_color(fl_gray_ramp(10));
|
||||
line_model_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
line_model_y->minor_grid_style(FL_DOT);
|
||||
line_model_y->major_step(5);
|
||||
line_model_y->label_step(1);
|
||||
line_model_y->axis_color(FL_BLACK);
|
||||
line_model_y->current();
|
||||
s->line_model_y = new Ca_Y_Axis(420, 240, 40, 90, "Amp");
|
||||
s->line_model_y->align(FL_ALIGN_LEFT);
|
||||
s->line_model_y->minimum(-0.1);
|
||||
s->line_model_y->maximum(0.1);
|
||||
s->line_model_y->minor_grid_color(fl_gray_ramp(20));
|
||||
s->line_model_y->major_grid_color(fl_gray_ramp(15));
|
||||
s->line_model_y->label_grid_color(fl_gray_ramp(10));
|
||||
s->line_model_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->line_model_y->minor_grid_style(FL_DOT);
|
||||
s->line_model_y->major_step(5);
|
||||
s->line_model_y->label_step(1);
|
||||
s->line_model_y->axis_color(FL_BLACK);
|
||||
s->line_model_y->current();
|
||||
|
||||
c_line_model->end();
|
||||
s->c_line_model->end();
|
||||
s->line_model_re = NULL;
|
||||
|
||||
audio_meter = new Fl_Audio_Meter(810, 40, 10, 250, "");
|
||||
audio_meter->box(FL_PLASTIC_UP_BOX);
|
||||
audio_meter->type(FL_VERT_AUDIO_METER);
|
||||
s->audio_meter = new Fl_Audio_Meter(810, 40, 10, 250, "");
|
||||
s->audio_meter->box(FL_PLASTIC_UP_BOX);
|
||||
s->audio_meter->type(FL_VERT_AUDIO_METER);
|
||||
|
||||
c_right->end();
|
||||
s->c_right->end();
|
||||
|
||||
Fl_Group::current()->resizable(c_right);
|
||||
w->end();
|
||||
w->show();
|
||||
Fl_Group::current()->resizable(s->c_right);
|
||||
s->w->end();
|
||||
s->w->show();
|
||||
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
p = fftw_plan_dft_1d(1024, in, out, FFTW_BACKWARD, FFTW_ESTIMATE);
|
||||
s->p = fftw_plan_dft_1d(1024, s->in, s->out, FFTW_BACKWARD, FFTW_ESTIMATE);
|
||||
for (i = 0; i < 1024; i++)
|
||||
{
|
||||
in[i][0] = 0.0;
|
||||
in[i][1] = 0.0;
|
||||
s->in[i][0] = 0.0;
|
||||
s->in[i][1] = 0.0;
|
||||
}
|
||||
#else
|
||||
p = fftw_create_plan(1024, FFTW_BACKWARD, FFTW_ESTIMATE);
|
||||
s->p = fftw_create_plan(1024, FFTW_BACKWARD, FFTW_ESTIMATE);
|
||||
for (i = 0; i < 1024; i++)
|
||||
{
|
||||
in[i].re = 0.0;
|
||||
in[i].im = 0.0;
|
||||
s->in[i].re = 0.0;
|
||||
s->in[i].im = 0.0;
|
||||
}
|
||||
#endif
|
||||
in_ptr = 0;
|
||||
s->in_ptr = 0;
|
||||
|
||||
Fl::check();
|
||||
return 0;
|
||||
|
@ -25,7 +25,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: echo_tests.c,v 1.35 2008/08/29 09:28:13 steveu Exp $
|
||||
* $Id: echo_tests.c,v 1.36 2008/09/04 14:40:05 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page echo_can_tests_page Line echo cancellation for voice tests
|
||||
@ -259,6 +259,7 @@ static level_measurement_device_t *level_measurement_device_create(int type)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if 0
|
||||
static void level_measurement_device_reset(level_measurement_device_t *dev)
|
||||
{
|
||||
int i;
|
||||
@ -279,6 +280,7 @@ static int level_measurement_device_release(level_measurement_device_t *s)
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
static float level_measurement_device_get_peak(level_measurement_device_t *dev)
|
||||
{
|
||||
@ -534,6 +536,7 @@ static int16_t far_noise_signal(void)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if 0
|
||||
static int16_t local_hoth_noise_signal(void)
|
||||
{
|
||||
static float hoth_noise = 0.0;
|
||||
@ -542,6 +545,7 @@ static int16_t local_hoth_noise_signal(void)
|
||||
return (int16_t) hoth_noise;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
static int16_t far_hoth_noise_signal(void)
|
||||
{
|
||||
@ -1483,7 +1487,7 @@ static int match_test_name(const char *name)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void simulate_ec(const char *argv[], int two_channel_file, int mode)
|
||||
static void simulate_ec(char *argv[], int two_channel_file, int mode)
|
||||
{
|
||||
echo_can_state_t *ctx;
|
||||
AFfilehandle txfile;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fax_decode.c,v 1.45 2008/08/13 00:11:30 steveu Exp $
|
||||
* $Id: fax_decode.c,v 1.48 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page fax_decode_page FAX decoder
|
||||
@ -219,16 +219,16 @@ static void hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok)
|
||||
/* Special conditions */
|
||||
switch (len)
|
||||
{
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
fprintf(stderr, "HDLC carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
fprintf(stderr, "HDLC carrier down\n");
|
||||
break;
|
||||
case PUTBIT_FRAMING_OK:
|
||||
case SIG_STATUS_FRAMING_OK:
|
||||
fprintf(stderr, "HDLC framing OK\n");
|
||||
break;
|
||||
case PUTBIT_ABORT:
|
||||
case SIG_STATUS_ABORT:
|
||||
/* Just ignore these */
|
||||
break;
|
||||
default:
|
||||
@ -331,19 +331,22 @@ static void v21_put_bit(void *user_data, int bit)
|
||||
/* Special conditions */
|
||||
switch (bit)
|
||||
{
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
fprintf(stderr, "V.21 Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
fprintf(stderr, "V.21 Training in progress\n");
|
||||
break;
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
fprintf(stderr, "V.21 Training succeeded\n");
|
||||
t4_begin();
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
fprintf(stderr, "V.21 Carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
fprintf(stderr, "V.21 Carrier down\n");
|
||||
t4_end();
|
||||
//t4_end();
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "V.21 Eh!\n");
|
||||
@ -364,18 +367,21 @@ static void v17_put_bit(void *user_data, int bit)
|
||||
/* Special conditions */
|
||||
switch (bit)
|
||||
{
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
fprintf(stderr, "V.17 Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
fprintf(stderr, "V.17 Training in progress\n");
|
||||
break;
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
fprintf(stderr, "V.17 Training succeeded\n");
|
||||
fast_trained = FAX_V17_RX;
|
||||
t4_begin();
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
fprintf(stderr, "V.17 Carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
fprintf(stderr, "V.17 Carrier down\n");
|
||||
t4_end();
|
||||
if (fast_trained == FAX_V17_RX)
|
||||
@ -410,18 +416,21 @@ static void v29_put_bit(void *user_data, int bit)
|
||||
/* Special conditions */
|
||||
switch (bit)
|
||||
{
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
//fprintf(stderr, "V.29 Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
fprintf(stderr, "V.29 Training in progress\n");
|
||||
break;
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
fprintf(stderr, "V.29 Training succeeded\n");
|
||||
fast_trained = FAX_V29_RX;
|
||||
t4_begin();
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
//fprintf(stderr, "V.29 Carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
//fprintf(stderr, "V.29 Carrier down\n");
|
||||
t4_end();
|
||||
if (fast_trained == FAX_V29_RX)
|
||||
@ -456,19 +465,23 @@ static void v27ter_put_bit(void *user_data, int bit)
|
||||
/* Special conditions */
|
||||
switch (bit)
|
||||
{
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
//fprintf(stderr, "V.27ter Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||
fprintf(stderr, "V.27ter Training in progress\n");
|
||||
break;
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
fprintf(stderr, "V.27ter Training succeeded\n");
|
||||
fast_trained = FAX_V27TER_RX;
|
||||
t4_begin();
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
//fprintf(stderr, "V.27ter Carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
//fprintf(stderr, "V.27ter Carrier down\n");
|
||||
t4_end();
|
||||
if (fast_trained == FAX_V27TER_RX)
|
||||
fast_trained = FAX_NONE;
|
||||
break;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fax_tester.c,v 1.13 2008/08/13 00:11:30 steveu Exp $
|
||||
* $Id: fax_tester.c,v 1.16 2008/09/09 14:05:55 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -146,18 +146,12 @@ static int modem_tx_status(void *user_data, int status)
|
||||
faxtester_state_t *s;
|
||||
|
||||
s = (faxtester_state_t *) user_data;
|
||||
printf("Tx status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
switch (status)
|
||||
{
|
||||
case MODEM_TX_STATUS_DATA_EXHAUSTED:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Tx data exhausted\n");
|
||||
break;
|
||||
case MODEM_TX_STATUS_SHUTDOWN_COMPLETE:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Tx shutdown complete\n");
|
||||
case SIG_STATUS_SHUTDOWN_COMPLETE:
|
||||
front_end_step_complete(s);
|
||||
break;
|
||||
default:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Tx status is %d\n", status);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -202,7 +196,7 @@ static int non_ecm_get_bit(void *user_data)
|
||||
if (s->image_ptr >= s->image_len)
|
||||
{
|
||||
s->image_buffer = NULL;
|
||||
return PUTBIT_END_OF_DATA;
|
||||
return SIG_STATUS_END_OF_DATA;
|
||||
}
|
||||
s->image_bit_ptr = 8;
|
||||
s->image_ptr++;
|
||||
@ -241,25 +235,20 @@ static void non_ecm_rx_status(void *user_data, int status)
|
||||
faxtester_state_t *s;
|
||||
|
||||
s = (faxtester_state_t *) user_data;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
break;
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier training failed\n");
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
s->modems.rx_trained = FALSE;
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
/* The modem is now trained */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier trained\n");
|
||||
s->modems.rx_trained = TRUE;
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier up\n");
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
s->modems.rx_signal_present = TRUE;
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM carrier down\n");
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
if (s->modems.rx_trained)
|
||||
{
|
||||
if (s->real_time_frame_handler)
|
||||
@ -268,9 +257,6 @@ static void non_ecm_rx_status(void *user_data, int status)
|
||||
s->modems.rx_signal_present = FALSE;
|
||||
s->modems.rx_trained = FALSE;
|
||||
break;
|
||||
default:
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "Unexpected non-ECM rx status - %d!\n", status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -293,37 +279,23 @@ static void hdlc_rx_status(void *user_data, int status)
|
||||
faxtester_state_t *s;
|
||||
|
||||
s = (faxtester_state_t *) user_data;
|
||||
fprintf(stderr, "HDLC carrier status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
break;
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier training failed\n");
|
||||
case SIG_STATUS_TRAINING_FAILED:
|
||||
s->modems.rx_trained = FALSE;
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
/* The modem is now trained */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier trained\n");
|
||||
s->modems.rx_trained = TRUE;
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier up\n");
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
s->modems.rx_signal_present = TRUE;
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC carrier down\n");
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
s->modems.rx_signal_present = FALSE;
|
||||
s->modems.rx_trained = FALSE;
|
||||
break;
|
||||
case PUTBIT_FRAMING_OK:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "HDLC framing OK\n");
|
||||
break;
|
||||
case PUTBIT_ABORT:
|
||||
/* Just ignore these */
|
||||
break;
|
||||
default:
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected HDLC special length - %d!\n", status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fax_tests.c,v 1.95 2008/08/29 09:28:13 steveu Exp $
|
||||
* $Id: fax_tests.c,v 1.96 2008/09/09 14:05:55 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page fax_tests_page FAX tests
|
||||
@ -167,7 +167,8 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
|
||||
printf("%d: Phase E: longest bad row run %d\n", i, t.longest_bad_row_run);
|
||||
printf("%d: Phase E: coding method %s\n", i, t4_encoding_to_str(t.encoding));
|
||||
printf("%d: Phase E: image size %d bytes\n", i, t.image_size);
|
||||
//printf("%d: Phase E: local ident '%s'\n", i, info->ident);
|
||||
if ((u = t30_get_tx_ident(s)))
|
||||
printf("%d: Phase E: local ident '%s'\n", i, u);
|
||||
if ((u = t30_get_rx_ident(s)))
|
||||
printf("%d: Phase E: remote ident '%s'\n", i, u);
|
||||
if ((u = t30_get_rx_country(s)))
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: fsk_tests.c,v 1.48 2008/08/29 09:28:13 steveu Exp $
|
||||
* $Id: fsk_tests.c,v 1.50 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page fsk_tests_page FSK modem tests
|
||||
@ -67,43 +67,14 @@ int cutoff_test_carrier = FALSE;
|
||||
|
||||
static int rx_status(void *user_data, int status)
|
||||
{
|
||||
printf("FSK rx status is %d\n", status);
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
printf("Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
printf("Training succeeded\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
printf("Carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
printf("Carrier down\n");
|
||||
break;
|
||||
default:
|
||||
printf("Eh! - %d\n", status);
|
||||
break;
|
||||
}
|
||||
printf("FSK rx status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int tx_status(void *user_data, int status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case MODEM_TX_STATUS_DATA_EXHAUSTED:
|
||||
printf("FSK tx data exhausted\n");
|
||||
break;
|
||||
case MODEM_TX_STATUS_SHUTDOWN_COMPLETE:
|
||||
printf("FSK tx shutdown complete\n");
|
||||
break;
|
||||
default:
|
||||
printf("FSK tx status is %d\n", status);
|
||||
break;
|
||||
}
|
||||
printf("FSK tx status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -122,26 +93,15 @@ static void put_bit(void *user_data, int bit)
|
||||
|
||||
static int cutoff_test_rx_status(void *user_data, int status)
|
||||
{
|
||||
printf("FSK rx status is %d\n", status);
|
||||
printf("FSK rx status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
printf("Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
printf("Training succeeded\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
//printf("Carrier up\n");
|
||||
case SIG_STATUS_CARRIER_UP:
|
||||
cutoff_test_carrier = TRUE;
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
//printf("Carrier down\n");
|
||||
case SIG_STATUS_CARRIER_DOWN:
|
||||
cutoff_test_carrier = FALSE;
|
||||
break;
|
||||
default:
|
||||
printf("Eh! - %d\n", status);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: g168_tests.c,v 1.16 2008/08/29 09:28:13 steveu Exp $
|
||||
* $Id: g168_tests.c,v 1.18 2008/09/04 14:40:05 steveu Exp $
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
@ -55,7 +55,7 @@ typedef struct
|
||||
signal_source_t local_css;
|
||||
signal_source_t far_css;
|
||||
|
||||
AFfilehandle afOpenFile_telephony_read(const char *name, int channels)
|
||||
static AFfilehandle afOpenFile_telephony_read(const char *name, int channels)
|
||||
{
|
||||
float x;
|
||||
AFfilehandle handle;
|
||||
@ -85,7 +85,8 @@ AFfilehandle afOpenFile_telephony_read(const char *name, int channels)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
AFfilehandle afOpenFile_telephony_write(const char *name, int channels)
|
||||
#if 0
|
||||
static AFfilehandle afOpenFile_telephony_write(const char *name, int channels)
|
||||
{
|
||||
AFfilesetup setup;
|
||||
AFfilehandle handle;
|
||||
@ -110,6 +111,7 @@ AFfilehandle afOpenFile_telephony_write(const char *name, int channels)
|
||||
return handle;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
static void signal_load(signal_source_t *sig, const char *name)
|
||||
{
|
||||
@ -367,6 +369,8 @@ int main(int argc, char *argv[])
|
||||
printf("\n");
|
||||
for (i = 0; i < (int) (sizeof(css_c1)/sizeof(css_c3[0])); i++)
|
||||
printf("%d\n", css_c3[i]);
|
||||
signal_free(&local_css);
|
||||
signal_free(&far_css);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: hdlc_tests.c,v 1.43 2008/05/13 13:17:25 steveu Exp $
|
||||
* $Id: hdlc_tests.c,v 1.46 2008/09/07 12:55:13 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -39,6 +39,7 @@ using both 16 and 32 bit CRCs.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "spandsp.h"
|
||||
@ -92,43 +93,15 @@ static void frame_handler(void *user_data, const uint8_t *pkt, int len, int ok)
|
||||
if (len < 0)
|
||||
{
|
||||
/* Special conditions */
|
||||
printf("HDLC rx status is %s (%d)\n", signal_status_to_str(len), len);
|
||||
switch (len)
|
||||
{
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
printf("Training in progress\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
printf("Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
printf("Training succeeded\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
printf("Carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
printf("Carrier down\n");
|
||||
break;
|
||||
case PUTBIT_FRAMING_OK:
|
||||
case SIG_STATUS_FRAMING_OK:
|
||||
framing_ok_reported = TRUE;
|
||||
framing_ok_reports++;
|
||||
//printf("Framing OK\n");
|
||||
break;
|
||||
case PUTBIT_END_OF_DATA:
|
||||
printf("End of data\n");
|
||||
break;
|
||||
case PUTBIT_ABORT:
|
||||
case SIG_STATUS_ABORT:
|
||||
abort_reported = TRUE;
|
||||
//printf("Abort\n");
|
||||
break;
|
||||
case PUTBIT_BREAK:
|
||||
printf("Break\n");
|
||||
break;
|
||||
case PUTBIT_OCTET_REPORT:
|
||||
printf("Octet report\n");
|
||||
break;
|
||||
default:
|
||||
printf("Eh!\n");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
@ -779,7 +752,7 @@ static int test_hdlc_octet_count_handling(void)
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
static void hdlc_tests(void)
|
||||
{
|
||||
printf("HDLC module tests\n");
|
||||
|
||||
@ -811,6 +784,76 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
printf("Tests passed.\n");
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void decode_handler(void *user_data, const uint8_t *pkt, int len, int ok)
|
||||
{
|
||||
if (len < 0)
|
||||
{
|
||||
/* Special conditions */
|
||||
printf("HDLC rx status is %s (%d)\n", signal_status_to_str(len), len);
|
||||
return;
|
||||
}
|
||||
if (ok)
|
||||
{
|
||||
printf("Good frame, len = %d\n", len);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Bad frame, len = %d\n", len);
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void decode_bitstream(const char *in_file_name)
|
||||
{
|
||||
char buf[1024];
|
||||
int bit;
|
||||
hdlc_rx_state_t rx;
|
||||
FILE *in;
|
||||
|
||||
if ((in = fopen(in_file_name, "r")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to open '%s'\n", in_file_name);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
hdlc_rx_init(&rx, TRUE, TRUE, 2, decode_handler, NULL);
|
||||
while (fgets(buf, 1024, in))
|
||||
{
|
||||
if (sscanf(buf, "Rx bit %*d - %d", &bit) == 1)
|
||||
{
|
||||
hdlc_rx_put_bit(&rx, bit);
|
||||
}
|
||||
}
|
||||
fclose(in);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int opt;
|
||||
const char *in_file_name;
|
||||
|
||||
in_file_name = NULL;
|
||||
while ((opt = getopt(argc, argv, "d:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'd':
|
||||
in_file_name = optarg;
|
||||
break;
|
||||
default:
|
||||
//usage();
|
||||
exit(2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (in_file_name)
|
||||
decode_bitstream(in_file_name);
|
||||
else
|
||||
hdlc_tests();
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: line_model_monitor.cpp,v 1.4 2008/05/27 15:08:21 steveu Exp $
|
||||
* $Id: line_model_monitor.cpp,v 1.5 2008/09/08 16:10:41 steveu Exp $
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -56,44 +56,49 @@
|
||||
#include "spandsp.h"
|
||||
#include "line_model_monitor.h"
|
||||
|
||||
Fl_Double_Window *w;
|
||||
struct line_model_monitor_s
|
||||
{
|
||||
Fl_Double_Window *w;
|
||||
|
||||
Fl_Audio_Meter *audio_meter;
|
||||
Fl_Audio_Meter *audio_meter;
|
||||
|
||||
Fl_Group *c_spec;
|
||||
Fl_Group *c_right;
|
||||
Fl_Group *c_can;
|
||||
Fl_Group *c_line_model;
|
||||
Fl_Group *c_spec;
|
||||
Fl_Group *c_right;
|
||||
Fl_Group *c_can;
|
||||
Fl_Group *c_line_model;
|
||||
|
||||
Ca_Canvas *canvas_spec;
|
||||
Ca_X_Axis *spec_freq;
|
||||
Ca_Y_Axis *spec_amp;
|
||||
Ca_Line *spec_re = NULL;
|
||||
double spec_re_plot[2*512];
|
||||
Ca_Canvas *canvas_spec;
|
||||
Ca_X_Axis *spec_freq;
|
||||
Ca_Y_Axis *spec_amp;
|
||||
Ca_Line *spec_re;
|
||||
double spec_re_plot[2*512];
|
||||
|
||||
Ca_Canvas *canvas_can;
|
||||
Ca_X_Axis *can_x;
|
||||
Ca_Y_Axis *can_y;
|
||||
Ca_Line *can_re = NULL;
|
||||
double can_re_plot[512];
|
||||
Ca_Canvas *canvas_can;
|
||||
Ca_X_Axis *can_x;
|
||||
Ca_Y_Axis *can_y;
|
||||
Ca_Line *can_re;
|
||||
double can_re_plot[512];
|
||||
|
||||
Ca_Canvas *canvas_line_model;
|
||||
Ca_X_Axis *line_model_x;
|
||||
Ca_Y_Axis *line_model_y;
|
||||
Ca_Line *line_model_re = NULL;
|
||||
double line_model_re_plot[512];
|
||||
Ca_Canvas *canvas_line_model;
|
||||
Ca_X_Axis *line_model_x;
|
||||
Ca_Y_Axis *line_model_y;
|
||||
Ca_Line *line_model_re;
|
||||
double line_model_re_plot[512];
|
||||
|
||||
int in_ptr;
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
double in[1024][2];
|
||||
double out[1024][2];
|
||||
#else
|
||||
fftw_complex in[1024];
|
||||
fftw_complex out[1024];
|
||||
#endif
|
||||
fftw_plan p;
|
||||
};
|
||||
|
||||
static int skip = 0;
|
||||
|
||||
int in_ptr;
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
double in[1024][2];
|
||||
double out[1024][2];
|
||||
#else
|
||||
fftw_complex in[1024];
|
||||
fftw_complex out[1024];
|
||||
#endif
|
||||
fftw_plan p;
|
||||
static struct line_model_monitor_s model;
|
||||
static struct line_model_monitor_s *s = &model;
|
||||
|
||||
int line_model_monitor_can_update(const float *coeffs, int len)
|
||||
{
|
||||
@ -101,25 +106,25 @@ int line_model_monitor_can_update(const float *coeffs, int len)
|
||||
float min;
|
||||
float max;
|
||||
|
||||
if (can_re)
|
||||
delete can_re;
|
||||
if (s->can_re)
|
||||
delete s->can_re;
|
||||
|
||||
canvas_can->current(canvas_can);
|
||||
s->canvas_can->current(s->canvas_can);
|
||||
i = 0;
|
||||
min = coeffs[i];
|
||||
max = coeffs[i];
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
can_re_plot[2*i] = i;
|
||||
can_re_plot[2*i + 1] = coeffs[i];
|
||||
s->can_re_plot[2*i] = i;
|
||||
s->can_re_plot[2*i + 1] = coeffs[i];
|
||||
if (min > coeffs[i])
|
||||
min = coeffs[i];
|
||||
if (max < coeffs[i])
|
||||
max = coeffs[i];
|
||||
}
|
||||
can_y->maximum((max == min) ? max + 0.2 : max);
|
||||
can_y->minimum(min);
|
||||
can_re = new Ca_Line(len, can_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
s->can_y->maximum((max == min) ? max + 0.2 : max);
|
||||
s->can_y->minimum(min);
|
||||
s->can_re = new Ca_Line(len, s->can_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
if (++skip >= 100)
|
||||
{
|
||||
skip = 0;
|
||||
@ -135,25 +140,25 @@ int line_model_monitor_line_model_update(const float *coeffs, int len)
|
||||
float min;
|
||||
float max;
|
||||
|
||||
if (line_model_re)
|
||||
delete line_model_re;
|
||||
if (s->line_model_re)
|
||||
delete s->line_model_re;
|
||||
|
||||
canvas_line_model->current(canvas_line_model);
|
||||
s->canvas_line_model->current(s->canvas_line_model);
|
||||
i = 0;
|
||||
min = coeffs[i];
|
||||
max = coeffs[i];
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
line_model_re_plot[2*i] = i;
|
||||
line_model_re_plot[2*i + 1] = coeffs[i];
|
||||
s->line_model_re_plot[2*i] = i;
|
||||
s->line_model_re_plot[2*i + 1] = coeffs[i];
|
||||
if (min > coeffs[i])
|
||||
min = coeffs[i];
|
||||
if (max < coeffs[i])
|
||||
max = coeffs[i];
|
||||
}
|
||||
line_model_y->maximum((max == min) ? max + 0.2 : max);
|
||||
line_model_y->minimum(min);
|
||||
line_model_re = new Ca_Line(len, line_model_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
s->line_model_y->maximum((max == min) ? max + 0.2 : max);
|
||||
s->line_model_y->minimum(min);
|
||||
s->line_model_re = new Ca_Line(len, s->line_model_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
if (++skip >= 100)
|
||||
{
|
||||
skip = 0;
|
||||
@ -169,18 +174,18 @@ int line_model_monitor_line_spectrum_update(const int16_t amp[], int len)
|
||||
int x;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
audio_meter->sample(amp[i]/32768.0);
|
||||
s->audio_meter->sample(amp[i]/32768.0);
|
||||
|
||||
if (in_ptr + len < 512)
|
||||
if (s->in_ptr + len < 512)
|
||||
{
|
||||
/* Just add this fragment to the buffer. */
|
||||
for (i = 0; i < len; i++)
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
in[in_ptr + i][0] = amp[i];
|
||||
s->in[s->in_ptr + i][0] = amp[i];
|
||||
#else
|
||||
in[in_ptr + i].re = amp[i];
|
||||
s->in[s->in_ptr + i].re = amp[i];
|
||||
#endif
|
||||
in_ptr += len;
|
||||
s->in_ptr += len;
|
||||
return 0;
|
||||
}
|
||||
if (len >= 512)
|
||||
@ -190,9 +195,9 @@ int line_model_monitor_line_spectrum_update(const int16_t amp[], int len)
|
||||
x = len - 512;
|
||||
for (i = 0; i < 512; i++)
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
in[i][0] = amp[x + i];
|
||||
s->in[i][0] = amp[x + i];
|
||||
#else
|
||||
in[i].re = amp[x + i];
|
||||
s->in[i].re = amp[x + i];
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -201,36 +206,36 @@ int line_model_monitor_line_spectrum_update(const int16_t amp[], int len)
|
||||
x = 512 - len;
|
||||
for (i = 0; i < x; i++)
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
in[i][0] = in[in_ptr - x + i][0];
|
||||
s->in[i][0] = s->in[s->in_ptr - x + i][0];
|
||||
#else
|
||||
in[i].re = in[in_ptr - x + i].re;
|
||||
s->in[i].re = s->in[s->in_ptr - x + i].re;
|
||||
#endif
|
||||
for (i = x; i < 512; i++)
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
in[i][0] = amp[i - x];
|
||||
s->in[i][0] = amp[i - x];
|
||||
#else
|
||||
in[i].re = amp[i - x];
|
||||
s->in[i].re = amp[i - x];
|
||||
#endif
|
||||
}
|
||||
in_ptr = 0;
|
||||
s->in_ptr = 0;
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
fftw_execute(p);
|
||||
fftw_execute(s->p);
|
||||
#else
|
||||
fftw_one(p, in, out);
|
||||
fftw_one(s->p, s->in, s->out);
|
||||
#endif
|
||||
if (spec_re)
|
||||
delete spec_re;
|
||||
canvas_spec->current(canvas_spec);
|
||||
if (s->spec_re)
|
||||
delete s->spec_re;
|
||||
s->canvas_spec->current(s->canvas_spec);
|
||||
for (i = 0; i < 512; i++)
|
||||
{
|
||||
spec_re_plot[2*i] = i*4000.0/512.0;
|
||||
s->spec_re_plot[2*i] = i*4000.0/512.0;
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
spec_re_plot[2*i + 1] = 20.0*log10(sqrt(out[i][0]*out[i][0] + out[i][1]*out[i][1])/(256.0*32768)) + 3.14;
|
||||
s->spec_re_plot[2*i + 1] = 20.0*log10(sqrt(s->out[i][0]*s->out[i][0] + s->out[i][1]*s->out[i][1])/(256.0*32768)) + 3.14;
|
||||
#else
|
||||
spec_re_plot[2*i + 1] = 20.0*log10(sqrt(out[i].re*out[i].re + out[i].im*out[i].im)/(256.0*32768)) + 3.14;
|
||||
s->spec_re_plot[2*i + 1] = 20.0*log10(sqrt(s->out[i].re*s->out[i].re + s->out[i].im*s->out[i].im)/(256.0*32768)) + 3.14;
|
||||
#endif
|
||||
}
|
||||
spec_re = new Ca_Line(512, spec_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
s->spec_re = new Ca_Line(512, s->spec_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
Fl::check();
|
||||
return 0;
|
||||
}
|
||||
@ -243,167 +248,171 @@ int start_line_model_monitor(int len)
|
||||
float y;
|
||||
int i;
|
||||
|
||||
w = new Fl_Double_Window(850, 400, "Telephone line model monitor");
|
||||
s->w = new Fl_Double_Window(850, 400, "Telephone line model monitor");
|
||||
|
||||
c_spec = new Fl_Group(0, 0, 380, 400);
|
||||
c_spec->box(FL_DOWN_BOX);
|
||||
c_spec->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
s->c_spec = new Fl_Group(0, 0, 380, 400);
|
||||
s->c_spec->box(FL_DOWN_BOX);
|
||||
s->c_spec->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
|
||||
canvas_spec = new Ca_Canvas(60, 30, 300, 300, "Spectrum");
|
||||
canvas_spec->box(FL_PLASTIC_DOWN_BOX);
|
||||
canvas_spec->color(7);
|
||||
canvas_spec->align(FL_ALIGN_TOP);
|
||||
canvas_spec->border(15);
|
||||
s->canvas_spec = new Ca_Canvas(60, 30, 300, 300, "Spectrum");
|
||||
s->canvas_spec->box(FL_PLASTIC_DOWN_BOX);
|
||||
s->canvas_spec->color(7);
|
||||
s->canvas_spec->align(FL_ALIGN_TOP);
|
||||
s->canvas_spec->border(15);
|
||||
|
||||
spec_freq = new Ca_X_Axis(65, 330, 290, 30, "Freq (Hz)");
|
||||
spec_freq->align(FL_ALIGN_BOTTOM);
|
||||
spec_freq->minimum(0);
|
||||
spec_freq->maximum(4000);
|
||||
spec_freq->label_format("%g");
|
||||
spec_freq->minor_grid_color(fl_gray_ramp(20));
|
||||
spec_freq->major_grid_color(fl_gray_ramp(15));
|
||||
spec_freq->label_grid_color(fl_gray_ramp(10));
|
||||
spec_freq->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
spec_freq->minor_grid_style(FL_DOT);
|
||||
spec_freq->major_step(5);
|
||||
spec_freq->label_step(1);
|
||||
spec_freq->axis_color(FL_BLACK);
|
||||
spec_freq->axis_align(CA_BOTTOM | CA_LINE);
|
||||
s->spec_freq = new Ca_X_Axis(65, 330, 290, 30, "Freq (Hz)");
|
||||
s->spec_freq->align(FL_ALIGN_BOTTOM);
|
||||
s->spec_freq->minimum(0);
|
||||
s->spec_freq->maximum(4000);
|
||||
s->spec_freq->label_format("%g");
|
||||
s->spec_freq->minor_grid_color(fl_gray_ramp(20));
|
||||
s->spec_freq->major_grid_color(fl_gray_ramp(15));
|
||||
s->spec_freq->label_grid_color(fl_gray_ramp(10));
|
||||
s->spec_freq->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->spec_freq->minor_grid_style(FL_DOT);
|
||||
s->spec_freq->major_step(5);
|
||||
s->spec_freq->label_step(1);
|
||||
s->spec_freq->axis_color(FL_BLACK);
|
||||
s->spec_freq->axis_align(CA_BOTTOM | CA_LINE);
|
||||
|
||||
spec_amp = new Ca_Y_Axis(20, 35, 40, 290, "Amp (dBmO)");
|
||||
spec_amp->align(FL_ALIGN_LEFT);
|
||||
spec_amp->minimum(-80.0);
|
||||
spec_amp->maximum(10.0);
|
||||
spec_amp->minor_grid_color(fl_gray_ramp(20));
|
||||
spec_amp->major_grid_color(fl_gray_ramp(15));
|
||||
spec_amp->label_grid_color(fl_gray_ramp(10));
|
||||
//spec_amp->grid_visible(CA_MINOR_TICK | CA_MAJOR_TICK | CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
spec_amp->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
spec_amp->minor_grid_style(FL_DOT);
|
||||
spec_amp->major_step(5);
|
||||
spec_amp->label_step(1);
|
||||
spec_amp->axis_color(FL_BLACK);
|
||||
s->spec_amp = new Ca_Y_Axis(20, 35, 40, 290, "Amp (dBmO)");
|
||||
s->spec_amp->align(FL_ALIGN_LEFT);
|
||||
s->spec_amp->minimum(-80.0);
|
||||
s->spec_amp->maximum(10.0);
|
||||
s->spec_amp->minor_grid_color(fl_gray_ramp(20));
|
||||
s->spec_amp->major_grid_color(fl_gray_ramp(15));
|
||||
s->spec_amp->label_grid_color(fl_gray_ramp(10));
|
||||
//s->spec_amp->grid_visible(CA_MINOR_TICK | CA_MAJOR_TICK | CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->spec_amp->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->spec_amp->minor_grid_style(FL_DOT);
|
||||
s->spec_amp->major_step(5);
|
||||
s->spec_amp->label_step(1);
|
||||
s->spec_amp->axis_color(FL_BLACK);
|
||||
|
||||
spec_amp->current();
|
||||
s->spec_amp->current();
|
||||
s->spec_re = NULL;
|
||||
|
||||
c_spec->end();
|
||||
s->c_spec->end();
|
||||
|
||||
c_right = new Fl_Group(440, 0, 465, 405);
|
||||
s->c_right = new Fl_Group(440, 0, 465, 405);
|
||||
|
||||
c_can = new Fl_Group(380, 0, 415, 200);
|
||||
c_can->box(FL_DOWN_BOX);
|
||||
c_can->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
c_can->current();
|
||||
s->c_can = new Fl_Group(380, 0, 415, 200);
|
||||
s->c_can->box(FL_DOWN_BOX);
|
||||
s->c_can->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
s->c_can->current();
|
||||
|
||||
canvas_can = new Ca_Canvas(460, 35, 300, 100, "??? coefficients");
|
||||
canvas_can->box(FL_PLASTIC_DOWN_BOX);
|
||||
canvas_can->color(7);
|
||||
canvas_can->align(FL_ALIGN_TOP);
|
||||
Fl_Group::current()->resizable(canvas_can);
|
||||
canvas_can->border(15);
|
||||
s->canvas_can = new Ca_Canvas(460, 35, 300, 100, "??? coefficients");
|
||||
s->canvas_can->box(FL_PLASTIC_DOWN_BOX);
|
||||
s->canvas_can->color(7);
|
||||
s->canvas_can->align(FL_ALIGN_TOP);
|
||||
Fl_Group::current()->resizable(s->canvas_can);
|
||||
s->canvas_can->border(15);
|
||||
|
||||
can_x = new Ca_X_Axis(465, 135, 290, 30, "Tap");
|
||||
can_x->align(FL_ALIGN_BOTTOM);
|
||||
can_x->minimum(0.0);
|
||||
can_x->maximum((float) len);
|
||||
can_x->label_format("%g");
|
||||
can_x->minor_grid_color(fl_gray_ramp(20));
|
||||
can_x->major_grid_color(fl_gray_ramp(15));
|
||||
can_x->label_grid_color(fl_gray_ramp(10));
|
||||
can_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
can_x->minor_grid_style(FL_DOT);
|
||||
can_x->major_step(5);
|
||||
can_x->label_step(1);
|
||||
can_x->axis_align(CA_BOTTOM | CA_LINE);
|
||||
can_x->axis_color(FL_BLACK);
|
||||
can_x->current();
|
||||
s->can_x = new Ca_X_Axis(465, 135, 290, 30, "Tap");
|
||||
s->can_x->align(FL_ALIGN_BOTTOM);
|
||||
s->can_x->minimum(0.0);
|
||||
s->can_x->maximum((float) len);
|
||||
s->can_x->label_format("%g");
|
||||
s->can_x->minor_grid_color(fl_gray_ramp(20));
|
||||
s->can_x->major_grid_color(fl_gray_ramp(15));
|
||||
s->can_x->label_grid_color(fl_gray_ramp(10));
|
||||
s->can_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->can_x->minor_grid_style(FL_DOT);
|
||||
s->can_x->major_step(5);
|
||||
s->can_x->label_step(1);
|
||||
s->can_x->axis_align(CA_BOTTOM | CA_LINE);
|
||||
s->can_x->axis_color(FL_BLACK);
|
||||
s->can_x->current();
|
||||
|
||||
can_y = new Ca_Y_Axis(420, 40, 40, 90, "Amp");
|
||||
can_y->align(FL_ALIGN_LEFT);
|
||||
can_y->minimum(-0.1);
|
||||
can_y->maximum(0.1);
|
||||
can_y->minor_grid_color(fl_gray_ramp(20));
|
||||
can_y->major_grid_color(fl_gray_ramp(15));
|
||||
can_y->label_grid_color(fl_gray_ramp(10));
|
||||
can_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
can_y->minor_grid_style(FL_DOT);
|
||||
can_y->major_step(5);
|
||||
can_y->label_step(1);
|
||||
can_y->axis_color(FL_BLACK);
|
||||
can_y->current();
|
||||
s->can_y = new Ca_Y_Axis(420, 40, 40, 90, "Amp");
|
||||
s->can_y->align(FL_ALIGN_LEFT);
|
||||
s->can_y->minimum(-0.1);
|
||||
s->can_y->maximum(0.1);
|
||||
s->can_y->minor_grid_color(fl_gray_ramp(20));
|
||||
s->can_y->major_grid_color(fl_gray_ramp(15));
|
||||
s->can_y->label_grid_color(fl_gray_ramp(10));
|
||||
s->can_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->can_y->minor_grid_style(FL_DOT);
|
||||
s->can_y->major_step(5);
|
||||
s->can_y->label_step(1);
|
||||
s->can_y->axis_color(FL_BLACK);
|
||||
s->can_y->current();
|
||||
|
||||
c_can->end();
|
||||
s->c_can->end();
|
||||
|
||||
c_line_model = new Fl_Group(380, 200, 415, 200);
|
||||
c_line_model->box(FL_DOWN_BOX);
|
||||
c_line_model->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
c_line_model->current();
|
||||
s->can_re = NULL;
|
||||
|
||||
canvas_line_model = new Ca_Canvas(460, 235, 300, 100, "Line impulse response model");
|
||||
canvas_line_model->box(FL_PLASTIC_DOWN_BOX);
|
||||
canvas_line_model->color(7);
|
||||
canvas_line_model->align(FL_ALIGN_TOP);
|
||||
Fl_Group::current()->resizable(canvas_line_model);
|
||||
canvas_line_model->border(15);
|
||||
s->c_line_model = new Fl_Group(380, 200, 415, 200);
|
||||
s->c_line_model->box(FL_DOWN_BOX);
|
||||
s->c_line_model->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
s->c_line_model->current();
|
||||
|
||||
line_model_x = new Ca_X_Axis(465, 335, 290, 30, "Tap");
|
||||
line_model_x->align(FL_ALIGN_BOTTOM);
|
||||
line_model_x->minimum(0.0);
|
||||
line_model_x->maximum((float) len);
|
||||
line_model_x->label_format("%g");
|
||||
line_model_x->minor_grid_color(fl_gray_ramp(20));
|
||||
line_model_x->major_grid_color(fl_gray_ramp(15));
|
||||
line_model_x->label_grid_color(fl_gray_ramp(10));
|
||||
line_model_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
line_model_x->minor_grid_style(FL_DOT);
|
||||
line_model_x->major_step(5);
|
||||
line_model_x->label_step(1);
|
||||
line_model_x->axis_align(CA_BOTTOM | CA_LINE);
|
||||
line_model_x->axis_color(FL_BLACK);
|
||||
line_model_x->current();
|
||||
s->canvas_line_model = new Ca_Canvas(460, 235, 300, 100, "Line impulse response model");
|
||||
s->canvas_line_model->box(FL_PLASTIC_DOWN_BOX);
|
||||
s->canvas_line_model->color(7);
|
||||
s->canvas_line_model->align(FL_ALIGN_TOP);
|
||||
Fl_Group::current()->resizable(s->canvas_line_model);
|
||||
s->canvas_line_model->border(15);
|
||||
|
||||
line_model_y = new Ca_Y_Axis(420, 240, 40, 90, "Amp");
|
||||
line_model_y->align(FL_ALIGN_LEFT);
|
||||
line_model_y->minimum(-0.1);
|
||||
line_model_y->maximum(0.1);
|
||||
line_model_y->minor_grid_color(fl_gray_ramp(20));
|
||||
line_model_y->major_grid_color(fl_gray_ramp(15));
|
||||
line_model_y->label_grid_color(fl_gray_ramp(10));
|
||||
line_model_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
line_model_y->minor_grid_style(FL_DOT);
|
||||
line_model_y->major_step(5);
|
||||
line_model_y->label_step(1);
|
||||
line_model_y->axis_color(FL_BLACK);
|
||||
line_model_y->current();
|
||||
s->line_model_x = new Ca_X_Axis(465, 335, 290, 30, "Tap");
|
||||
s->line_model_x->align(FL_ALIGN_BOTTOM);
|
||||
s->line_model_x->minimum(0.0);
|
||||
s->line_model_x->maximum((float) len);
|
||||
s->line_model_x->label_format("%g");
|
||||
s->line_model_x->minor_grid_color(fl_gray_ramp(20));
|
||||
s->line_model_x->major_grid_color(fl_gray_ramp(15));
|
||||
s->line_model_x->label_grid_color(fl_gray_ramp(10));
|
||||
s->line_model_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->line_model_x->minor_grid_style(FL_DOT);
|
||||
s->line_model_x->major_step(5);
|
||||
s->line_model_x->label_step(1);
|
||||
s->line_model_x->axis_align(CA_BOTTOM | CA_LINE);
|
||||
s->line_model_x->axis_color(FL_BLACK);
|
||||
s->line_model_x->current();
|
||||
|
||||
c_line_model->end();
|
||||
s->line_model_y = new Ca_Y_Axis(420, 240, 40, 90, "Amp");
|
||||
s->line_model_y->align(FL_ALIGN_LEFT);
|
||||
s->line_model_y->minimum(-0.1);
|
||||
s->line_model_y->maximum(0.1);
|
||||
s->line_model_y->minor_grid_color(fl_gray_ramp(20));
|
||||
s->line_model_y->major_grid_color(fl_gray_ramp(15));
|
||||
s->line_model_y->label_grid_color(fl_gray_ramp(10));
|
||||
s->line_model_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->line_model_y->minor_grid_style(FL_DOT);
|
||||
s->line_model_y->major_step(5);
|
||||
s->line_model_y->label_step(1);
|
||||
s->line_model_y->axis_color(FL_BLACK);
|
||||
s->line_model_y->current();
|
||||
s->line_model_re = NULL;
|
||||
|
||||
audio_meter = new Fl_Audio_Meter(810, 40, 10, 250, "");
|
||||
audio_meter->box(FL_PLASTIC_UP_BOX);
|
||||
audio_meter->type(FL_VERT_AUDIO_METER);
|
||||
s->c_line_model->end();
|
||||
|
||||
c_right->end();
|
||||
s->audio_meter = new Fl_Audio_Meter(810, 40, 10, 250, "");
|
||||
s->audio_meter->box(FL_PLASTIC_UP_BOX);
|
||||
s->audio_meter->type(FL_VERT_AUDIO_METER);
|
||||
|
||||
Fl_Group::current()->resizable(c_right);
|
||||
w->end();
|
||||
w->show();
|
||||
s->c_right->end();
|
||||
|
||||
Fl_Group::current()->resizable(s->c_right);
|
||||
s->w->end();
|
||||
s->w->show();
|
||||
|
||||
#if defined(HAVE_FFTW3_H)
|
||||
p = fftw_plan_dft_1d(1024, in, out, FFTW_BACKWARD, FFTW_ESTIMATE);
|
||||
s->p = fftw_plan_dft_1d(1024, s->in, s->out, FFTW_BACKWARD, FFTW_ESTIMATE);
|
||||
for (i = 0; i < 1024; i++)
|
||||
{
|
||||
in[i][0] = 0.0;
|
||||
in[i][1] = 0.0;
|
||||
s->in[i][0] = 0.0;
|
||||
s->in[i][1] = 0.0;
|
||||
}
|
||||
#else
|
||||
p = fftw_create_plan(1024, FFTW_BACKWARD, FFTW_ESTIMATE);
|
||||
s->p = fftw_create_plan(1024, FFTW_BACKWARD, FFTW_ESTIMATE);
|
||||
for (i = 0; i < 1024; i++)
|
||||
{
|
||||
in[i].re = 0.0;
|
||||
in[i].im = 0.0;
|
||||
s->in[i].re = 0.0;
|
||||
s->in[i].im = 0.0;
|
||||
}
|
||||
#endif
|
||||
in_ptr = 0;
|
||||
s->in_ptr = 0;
|
||||
|
||||
Fl::check();
|
||||
return 0;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: media_monitor.cpp,v 1.4 2008/05/27 15:08:21 steveu Exp $
|
||||
* $Id: media_monitor.cpp,v 1.5 2008/09/08 16:10:41 steveu Exp $
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -50,34 +50,37 @@
|
||||
#include "spandsp.h"
|
||||
#include "media_monitor.h"
|
||||
|
||||
Fl_Double_Window *w;
|
||||
struct line_model_monitor_s
|
||||
{
|
||||
Fl_Double_Window *w;
|
||||
|
||||
Fl_Group *c_right;
|
||||
Fl_Group *c_sent;
|
||||
Fl_Group *c_received;
|
||||
Fl_Group *c_right;
|
||||
Fl_Group *c_sent;
|
||||
Fl_Group *c_received;
|
||||
|
||||
Ca_Canvas *canvas_sent;
|
||||
Ca_X_Axis *sent_x;
|
||||
Ca_Y_Axis *sent_y;
|
||||
Ca_Line *sent_re = NULL;
|
||||
double sent_re_plot[1000];
|
||||
double sent_re_plot_min;
|
||||
double sent_re_plot_max;
|
||||
Ca_Canvas *canvas_sent;
|
||||
Ca_X_Axis *sent_x;
|
||||
Ca_Y_Axis *sent_y;
|
||||
Ca_Line *sent_re;
|
||||
double sent_re_plot[1000];
|
||||
double sent_re_plot_min;
|
||||
double sent_re_plot_max;
|
||||
|
||||
Ca_Canvas *canvas_received;
|
||||
Ca_X_Axis *received_x;
|
||||
Ca_Y_Axis *received_y;
|
||||
Ca_Line *received_delays = NULL;
|
||||
double received_delays_plot[4000];
|
||||
double received_delays_plot_max;
|
||||
int min_diff;
|
||||
int max_diff;
|
||||
Ca_Canvas *canvas_received;
|
||||
Ca_X_Axis *received_x;
|
||||
Ca_Y_Axis *received_y;
|
||||
Ca_Line *received_delays;
|
||||
double received_delays_plot[4000];
|
||||
double received_delays_plot_max;
|
||||
int min_diff;
|
||||
int max_diff;
|
||||
|
||||
int highest_seq_no_seen = -1;
|
||||
int highest_seq_no_seen;
|
||||
};
|
||||
|
||||
static int skip = 0;
|
||||
|
||||
int in_ptr;
|
||||
static struct line_model_monitor_s media;
|
||||
static struct line_model_monitor_s *s = &media;
|
||||
|
||||
void media_monitor_rx(int seq_no, double departure_time, double arrival_time)
|
||||
{
|
||||
@ -85,61 +88,61 @@ void media_monitor_rx(int seq_no, double departure_time, double arrival_time)
|
||||
int diff;
|
||||
int i;
|
||||
|
||||
if (received_delays)
|
||||
delete received_delays;
|
||||
if (s->received_delays)
|
||||
delete s->received_delays;
|
||||
|
||||
canvas_received->current(canvas_received);
|
||||
s->canvas_received->current(s->canvas_received);
|
||||
fdiff = (arrival_time - departure_time)*1000.0;
|
||||
diff = (int) fdiff;
|
||||
if (diff < 0)
|
||||
diff = 0;
|
||||
else if (diff > 1999)
|
||||
diff = 1999;
|
||||
received_delays_plot[2*diff + 1]++;
|
||||
if (received_delays_plot[2*diff + 1] > received_delays_plot_max)
|
||||
s->received_delays_plot[2*diff + 1]++;
|
||||
if (s->received_delays_plot[2*diff + 1] > s->received_delays_plot_max)
|
||||
{
|
||||
received_delays_plot_max = received_delays_plot[2*diff + 1];
|
||||
received_y->maximum(received_delays_plot_max);
|
||||
s->received_delays_plot_max = s->received_delays_plot[2*diff + 1];
|
||||
s->received_y->maximum(s->received_delays_plot_max);
|
||||
}
|
||||
if (diff > max_diff)
|
||||
if (diff > s->max_diff)
|
||||
{
|
||||
max_diff = diff;
|
||||
received_x->maximum((double) max_diff);
|
||||
s->max_diff = diff;
|
||||
s->received_x->maximum((double) s->max_diff);
|
||||
}
|
||||
if (diff < min_diff)
|
||||
if (diff < s->min_diff)
|
||||
{
|
||||
min_diff = diff - 1;
|
||||
received_x->minimum((double) min_diff);
|
||||
s->min_diff = diff - 1;
|
||||
s->received_x->minimum((double) s->min_diff);
|
||||
}
|
||||
|
||||
received_delays = new Ca_Line(2000, received_delays_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
s->received_delays = new Ca_Line(2000, s->received_delays_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
|
||||
if (sent_re)
|
||||
delete sent_re;
|
||||
if (s->sent_re)
|
||||
delete s->sent_re;
|
||||
|
||||
canvas_sent->current(canvas_sent);
|
||||
s->canvas_sent->current(s->canvas_sent);
|
||||
|
||||
if (seq_no > highest_seq_no_seen + 1)
|
||||
if (seq_no > s->highest_seq_no_seen + 1)
|
||||
{
|
||||
for (i = highest_seq_no_seen + 1; i < seq_no; i++)
|
||||
sent_re_plot[2*(i%500) + 1] = 0.0;
|
||||
for (i = s->highest_seq_no_seen + 1; i < seq_no; i++)
|
||||
s->sent_re_plot[2*(i%500) + 1] = 0.0;
|
||||
}
|
||||
sent_re_plot[2*(seq_no%500) + 1] = fdiff;
|
||||
s->sent_re_plot[2*(seq_no%500) + 1] = fdiff;
|
||||
|
||||
if (fdiff > sent_re_plot_max)
|
||||
if (fdiff > s->sent_re_plot_max)
|
||||
{
|
||||
sent_re_plot_max = fdiff;
|
||||
sent_y->maximum(sent_re_plot_max);
|
||||
s->sent_re_plot_max = fdiff;
|
||||
s->sent_y->maximum(s->sent_re_plot_max);
|
||||
}
|
||||
if (fdiff < sent_re_plot_min)
|
||||
if (fdiff < s->sent_re_plot_min)
|
||||
{
|
||||
sent_re_plot_min = fdiff - 1.0;
|
||||
sent_y->minimum(sent_re_plot_min);
|
||||
s->sent_re_plot_min = fdiff - 1.0;
|
||||
s->sent_y->minimum(s->sent_re_plot_min);
|
||||
}
|
||||
sent_re = new Ca_Line(500, sent_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
s->sent_re = new Ca_Line(500, s->sent_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
|
||||
if (seq_no > highest_seq_no_seen)
|
||||
highest_seq_no_seen = seq_no;
|
||||
if (seq_no > s->highest_seq_no_seen)
|
||||
s->highest_seq_no_seen = seq_no;
|
||||
|
||||
if (++skip >= 100)
|
||||
{
|
||||
@ -159,116 +162,118 @@ int start_media_monitor(void)
|
||||
|
||||
len = 128;
|
||||
|
||||
w = new Fl_Double_Window(465, 400, "IP streaming media monitor");
|
||||
s->w = new Fl_Double_Window(465, 400, "IP streaming media monitor");
|
||||
|
||||
c_right = new Fl_Group(0, 0, 465, 405);
|
||||
s->c_right = new Fl_Group(0, 0, 465, 405);
|
||||
|
||||
c_sent = new Fl_Group(0, 0, 465, 200);
|
||||
c_sent->box(FL_DOWN_BOX);
|
||||
c_sent->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
c_sent->current();
|
||||
s->c_sent = new Fl_Group(0, 0, 465, 200);
|
||||
s->c_sent->box(FL_DOWN_BOX);
|
||||
s->c_sent->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
s->c_sent->current();
|
||||
|
||||
canvas_sent = new Ca_Canvas(110, 35, 300, 100, "Packet delays");
|
||||
canvas_sent->box(FL_PLASTIC_DOWN_BOX);
|
||||
canvas_sent->color(7);
|
||||
canvas_sent->align(FL_ALIGN_TOP);
|
||||
Fl_Group::current()->resizable(canvas_sent);
|
||||
canvas_sent->border(15);
|
||||
s->canvas_sent = new Ca_Canvas(110, 35, 300, 100, "Packet delays");
|
||||
s->canvas_sent->box(FL_PLASTIC_DOWN_BOX);
|
||||
s->canvas_sent->color(7);
|
||||
s->canvas_sent->align(FL_ALIGN_TOP);
|
||||
Fl_Group::current()->resizable(s->canvas_sent);
|
||||
s->canvas_sent->border(15);
|
||||
|
||||
sent_x = new Ca_X_Axis(115, 135, 290, 30, "Packet");
|
||||
sent_x->align(FL_ALIGN_BOTTOM);
|
||||
sent_x->minimum(0.0);
|
||||
sent_x->maximum(500.0);
|
||||
sent_x->label_format("%g");
|
||||
sent_x->minor_grid_color(fl_gray_ramp(20));
|
||||
sent_x->major_grid_color(fl_gray_ramp(15));
|
||||
sent_x->label_grid_color(fl_gray_ramp(10));
|
||||
sent_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
sent_x->minor_grid_style(FL_DOT);
|
||||
sent_x->major_step(5);
|
||||
sent_x->label_step(1);
|
||||
sent_x->axis_align(CA_BOTTOM | CA_LINE);
|
||||
sent_x->axis_color(FL_BLACK);
|
||||
sent_x->current();
|
||||
s->sent_x = new Ca_X_Axis(115, 135, 290, 30, "Packet");
|
||||
s->sent_x->align(FL_ALIGN_BOTTOM);
|
||||
s->sent_x->minimum(0.0);
|
||||
s->sent_x->maximum(500.0);
|
||||
s->sent_x->label_format("%g");
|
||||
s->sent_x->minor_grid_color(fl_gray_ramp(20));
|
||||
s->sent_x->major_grid_color(fl_gray_ramp(15));
|
||||
s->sent_x->label_grid_color(fl_gray_ramp(10));
|
||||
s->sent_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->sent_x->minor_grid_style(FL_DOT);
|
||||
s->sent_x->major_step(5);
|
||||
s->sent_x->label_step(1);
|
||||
s->sent_x->axis_align(CA_BOTTOM | CA_LINE);
|
||||
s->sent_x->axis_color(FL_BLACK);
|
||||
s->sent_x->current();
|
||||
|
||||
sent_y = new Ca_Y_Axis(60, 40, 50, 90, "Delay\n(ms)");
|
||||
sent_y->align(FL_ALIGN_LEFT);
|
||||
sent_y->minimum(0.0);
|
||||
sent_y->maximum(2000.0);
|
||||
sent_y->minor_grid_color(fl_gray_ramp(20));
|
||||
sent_y->major_grid_color(fl_gray_ramp(15));
|
||||
sent_y->label_grid_color(fl_gray_ramp(10));
|
||||
sent_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
sent_y->minor_grid_style(FL_DOT);
|
||||
sent_y->major_step(5);
|
||||
sent_y->label_step(1);
|
||||
sent_y->axis_color(FL_BLACK);
|
||||
sent_y->current();
|
||||
s->sent_y = new Ca_Y_Axis(60, 40, 50, 90, "Delay\n(ms)");
|
||||
s->sent_y->align(FL_ALIGN_LEFT);
|
||||
s->sent_y->minimum(0.0);
|
||||
s->sent_y->maximum(2000.0);
|
||||
s->sent_y->minor_grid_color(fl_gray_ramp(20));
|
||||
s->sent_y->major_grid_color(fl_gray_ramp(15));
|
||||
s->sent_y->label_grid_color(fl_gray_ramp(10));
|
||||
s->sent_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->sent_y->minor_grid_style(FL_DOT);
|
||||
s->sent_y->major_step(5);
|
||||
s->sent_y->label_step(1);
|
||||
s->sent_y->axis_color(FL_BLACK);
|
||||
s->sent_y->current();
|
||||
|
||||
c_sent->end();
|
||||
s->c_sent->end();
|
||||
|
||||
c_received = new Fl_Group(0, 200, 465, 200);
|
||||
c_received->box(FL_DOWN_BOX);
|
||||
c_received->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
c_received->current();
|
||||
s->c_received = new Fl_Group(0, 200, 465, 200);
|
||||
s->c_received->box(FL_DOWN_BOX);
|
||||
s->c_received->align(FL_ALIGN_TOP | FL_ALIGN_INSIDE);
|
||||
s->c_received->current();
|
||||
|
||||
canvas_received = new Ca_Canvas(110, 235, 300, 100, "Delay spread");
|
||||
canvas_received->box(FL_PLASTIC_DOWN_BOX);
|
||||
canvas_received->color(7);
|
||||
canvas_received->align(FL_ALIGN_TOP);
|
||||
Fl_Group::current()->resizable(canvas_received);
|
||||
canvas_received->border(15);
|
||||
s->canvas_received = new Ca_Canvas(110, 235, 300, 100, "Delay spread");
|
||||
s->canvas_received->box(FL_PLASTIC_DOWN_BOX);
|
||||
s->canvas_received->color(7);
|
||||
s->canvas_received->align(FL_ALIGN_TOP);
|
||||
Fl_Group::current()->resizable(s->canvas_received);
|
||||
s->canvas_received->border(15);
|
||||
|
||||
received_x = new Ca_X_Axis(115, 335, 290, 30, "Delay (ms)");
|
||||
received_x->align(FL_ALIGN_BOTTOM);
|
||||
received_x->minimum(0.0);
|
||||
received_x->maximum(2000.0);
|
||||
received_x->label_format("%g");
|
||||
received_x->minor_grid_color(fl_gray_ramp(20));
|
||||
received_x->major_grid_color(fl_gray_ramp(15));
|
||||
received_x->label_grid_color(fl_gray_ramp(10));
|
||||
received_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
received_x->minor_grid_style(FL_DOT);
|
||||
received_x->major_step(5);
|
||||
received_x->label_step(1);
|
||||
received_x->axis_align(CA_BOTTOM | CA_LINE);
|
||||
received_x->axis_color(FL_BLACK);
|
||||
received_x->current();
|
||||
s->received_x = new Ca_X_Axis(115, 335, 290, 30, "Delay (ms)");
|
||||
s->received_x->align(FL_ALIGN_BOTTOM);
|
||||
s->received_x->minimum(0.0);
|
||||
s->received_x->maximum(2000.0);
|
||||
s->received_x->label_format("%g");
|
||||
s->received_x->minor_grid_color(fl_gray_ramp(20));
|
||||
s->received_x->major_grid_color(fl_gray_ramp(15));
|
||||
s->received_x->label_grid_color(fl_gray_ramp(10));
|
||||
s->received_x->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->received_x->minor_grid_style(FL_DOT);
|
||||
s->received_x->major_step(5);
|
||||
s->received_x->label_step(1);
|
||||
s->received_x->axis_align(CA_BOTTOM | CA_LINE);
|
||||
s->received_x->axis_color(FL_BLACK);
|
||||
s->received_x->current();
|
||||
|
||||
received_y = new Ca_Y_Axis(60, 240, 50, 90, "Freq");
|
||||
received_y->align(FL_ALIGN_LEFT);
|
||||
received_y->minimum(0.0);
|
||||
received_y->maximum(50.0);
|
||||
received_y->minor_grid_color(fl_gray_ramp(20));
|
||||
received_y->major_grid_color(fl_gray_ramp(15));
|
||||
received_y->label_grid_color(fl_gray_ramp(10));
|
||||
received_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
received_y->minor_grid_style(FL_DOT);
|
||||
received_y->major_step(5);
|
||||
received_y->label_step(1);
|
||||
received_y->axis_color(FL_BLACK);
|
||||
received_y->current();
|
||||
s->received_y = new Ca_Y_Axis(60, 240, 50, 90, "Freq");
|
||||
s->received_y->align(FL_ALIGN_LEFT);
|
||||
s->received_y->minimum(0.0);
|
||||
s->received_y->maximum(50.0);
|
||||
s->received_y->minor_grid_color(fl_gray_ramp(20));
|
||||
s->received_y->major_grid_color(fl_gray_ramp(15));
|
||||
s->received_y->label_grid_color(fl_gray_ramp(10));
|
||||
s->received_y->grid_visible(CA_LABEL_GRID | CA_ALWAYS_VISIBLE);
|
||||
s->received_y->minor_grid_style(FL_DOT);
|
||||
s->received_y->major_step(5);
|
||||
s->received_y->label_step(1);
|
||||
s->received_y->axis_color(FL_BLACK);
|
||||
s->received_y->current();
|
||||
|
||||
for (i = 0; i < 2000; i++)
|
||||
received_delays_plot[2*i] = i;
|
||||
received_delays_plot_max = 0.0;
|
||||
min_diff = 2000;
|
||||
max_diff = 0;
|
||||
s->received_delays_plot[2*i] = i;
|
||||
s->received_delays_plot_max = 0.0;
|
||||
s->min_diff = 2000;
|
||||
s->max_diff = 0;
|
||||
|
||||
s->received_delays = NULL;
|
||||
s->highest_seq_no_seen = -1;
|
||||
|
||||
for (i = 0; i < 500; i++)
|
||||
sent_re_plot[2*i] = i;
|
||||
sent_re_plot_min = 99999.0;
|
||||
sent_re_plot_max = 0.0;
|
||||
s->sent_re_plot[2*i] = i;
|
||||
s->sent_re_plot_min = 99999.0;
|
||||
s->sent_re_plot_max = 0.0;
|
||||
s->sent_re = NULL;
|
||||
|
||||
c_received->end();
|
||||
s->c_received->end();
|
||||
|
||||
c_right->end();
|
||||
s->c_right->end();
|
||||
|
||||
Fl_Group::current()->resizable(c_right);
|
||||
w->end();
|
||||
w->show();
|
||||
|
||||
in_ptr = 0;
|
||||
Fl_Group::current()->resizable(s->c_right);
|
||||
s->w->end();
|
||||
s->w->show();
|
||||
|
||||
Fl::check();
|
||||
return 0;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: modem_monitor.cpp,v 1.15 2008/05/27 15:08:21 steveu Exp $
|
||||
* $Id: modem_monitor.cpp,v 1.17 2008/09/04 14:40:05 steveu Exp $
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -54,6 +54,8 @@
|
||||
#define SYMBOL_TRACKER_POINTS 12000
|
||||
#define CARRIER_TRACKER_POINTS 12000
|
||||
|
||||
#define FP_FACTOR 4096
|
||||
|
||||
struct qam_monitor_s
|
||||
{
|
||||
Fl_Double_Window *w;
|
||||
@ -165,9 +167,9 @@ int qam_monitor_update_equalizer(qam_monitor_t *s, const complexf_t *coeffs, int
|
||||
break;
|
||||
if (isnan(coeffs[i].im) || isinf(coeffs[i].im))
|
||||
break;
|
||||
if (coeffs[i].re < -20.0 || coeffs[i].re > 20.0)
|
||||
if (coeffs[i].re < -20.0f || coeffs[i].re > 20.0f)
|
||||
break;
|
||||
if (coeffs[i].im < -20.0 || coeffs[i].im > 20.0)
|
||||
if (coeffs[i].im < -20.0f || coeffs[i].im > 20.0f)
|
||||
break;
|
||||
}
|
||||
if (i != len)
|
||||
@ -214,6 +216,55 @@ int qam_monitor_update_equalizer(qam_monitor_t *s, const complexf_t *coeffs, int
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
int qam_monitor_update_int_equalizer(qam_monitor_t *s, const complexi16_t *coeffs, int len)
|
||||
{
|
||||
int i;
|
||||
float min;
|
||||
float max;
|
||||
|
||||
if (s->eq_re)
|
||||
delete s->eq_re;
|
||||
if (s->eq_im)
|
||||
delete s->eq_im;
|
||||
|
||||
s->canvas_eq->current(s->canvas_eq);
|
||||
i = 0;
|
||||
min = coeffs[i].re;
|
||||
if (min > coeffs[i].im)
|
||||
min = coeffs[i].im;
|
||||
max = coeffs[i].re;
|
||||
if (max < coeffs[i].im)
|
||||
max = coeffs[i].im;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
s->eq_re_plot[2*i] = (i - len/2)/2.0f;
|
||||
s->eq_re_plot[2*i + 1] = coeffs[i].re/(float) FP_FACTOR;
|
||||
if (min > coeffs[i].re)
|
||||
min = coeffs[i].re;
|
||||
if (max < coeffs[i].re)
|
||||
max = coeffs[i].re;
|
||||
|
||||
s->eq_im_plot[2*i] = (i - len/2)/2.0f;
|
||||
s->eq_im_plot[2*i + 1] = coeffs[i].im/(float) FP_FACTOR;
|
||||
if (min > coeffs[i].im)
|
||||
min = coeffs[i].im;
|
||||
if (max < coeffs[i].im)
|
||||
max = coeffs[i].im;
|
||||
}
|
||||
min /= (float) FP_FACTOR;
|
||||
max /= (float) FP_FACTOR;
|
||||
|
||||
s->eq_x->minimum(-len/4.0);
|
||||
s->eq_x->maximum(len/4.0);
|
||||
s->eq_y->maximum((max == min) ? max + 0.2 : max);
|
||||
s->eq_y->minimum(min);
|
||||
s->eq_re = new Ca_Line(len, s->eq_re_plot, 0, 0, FL_BLUE, CA_NO_POINT);
|
||||
s->eq_im = new Ca_Line(len, s->eq_im_plot, 0, 0, FL_RED, CA_NO_POINT);
|
||||
Fl::check();
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
int qam_monitor_update_symbol_tracking(qam_monitor_t *s, float total_correction)
|
||||
{
|
||||
int i;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: modem_monitor.h,v 1.15 2008/04/26 13:39:17 steveu Exp $
|
||||
* $Id: modem_monitor.h,v 1.16 2008/09/03 13:41:42 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page constel_page Modem performance monitoring
|
||||
@ -56,6 +56,7 @@ qam_monitor_t *qam_monitor_init(float constel_width, const char *tag);
|
||||
int qam_monitor_clear_constel(qam_monitor_t *s);
|
||||
int qam_monitor_update_constel(qam_monitor_t *s, const complexf_t *pt);
|
||||
int qam_monitor_update_equalizer(qam_monitor_t *s, const complexf_t *coeffs, int len);
|
||||
int qam_monitor_update_int_equalizer(qam_monitor_t *s, const complexi16_t *coeffs, int len);
|
||||
int qam_monitor_update_symbol_tracking(qam_monitor_t *s, float total_correction);
|
||||
int qam_monitor_update_carrier_tracking(qam_monitor_t *s, float carrier);
|
||||
int qam_monitor_update_audio_level(qam_monitor_t *s, const int16_t amp[], int len);
|
||||
|
@ -23,7 +23,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: oki_adpcm_tests.c,v 1.34 2008/08/29 09:28:13 steveu Exp $
|
||||
* $Id: oki_adpcm_tests.c,v 1.35 2008/09/04 14:40:05 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -70,7 +70,6 @@ int main(int argc, char *argv[])
|
||||
int outframes;
|
||||
int oki_bytes;
|
||||
int bit_rate;
|
||||
float x;
|
||||
double pre_energy;
|
||||
double post_energy;
|
||||
double diff_energy;
|
||||
|
@ -17,7 +17,7 @@
|
||||
# License along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id: regression_tests.sh,v 1.51 2008/05/03 07:37:06 steveu Exp $
|
||||
# $Id: regression_tests.sh,v 1.52 2008/09/02 13:56:10 steveu Exp $
|
||||
#
|
||||
|
||||
ITUTESTS_TIF=../test-data/itu/fax/itutests.tif
|
||||
@ -517,6 +517,15 @@ then
|
||||
fi
|
||||
echo t38_gateway_to_terminal_tests completed OK
|
||||
|
||||
./t38_non_ecm_buffer_tests >$STDOUT_DEST 2>$STDERR_DEST
|
||||
RETVAL=$?
|
||||
if [ $RETVAL != 0 ]
|
||||
then
|
||||
echo t38_non_ecm_buffer_tests failed!
|
||||
exit $RETVAL
|
||||
fi
|
||||
echo t38_non_ecm_buffer_tests completed OK
|
||||
|
||||
rm -f t38.tif
|
||||
./t38_terminal_to_gateway_tests >$STDOUT_DEST 2>$STDERR_DEST
|
||||
RETVAL=$?
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: super_tone_rx_tests.c,v 1.28 2008/05/13 13:17:26 steveu Exp $
|
||||
* $Id: super_tone_rx_tests.c,v 1.29 2008/08/30 16:47:35 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -264,7 +264,7 @@ static void get_tone_set(super_tone_rx_descriptor_t *desc, const char *tone_file
|
||||
xmlDocPtr doc;
|
||||
xmlNsPtr ns;
|
||||
xmlNodePtr cur;
|
||||
#if 0
|
||||
#if 1
|
||||
xmlValidCtxt valid;
|
||||
#endif
|
||||
xmlChar *x;
|
||||
@ -272,15 +272,14 @@ static void get_tone_set(super_tone_rx_descriptor_t *desc, const char *tone_file
|
||||
ns = NULL;
|
||||
xmlKeepBlanksDefault(0);
|
||||
xmlCleanupParser();
|
||||
doc = xmlParseFile(tone_file);
|
||||
if (doc == NULL)
|
||||
if ((doc = xmlParseFile(tone_file)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "No document\n");
|
||||
exit(2);
|
||||
}
|
||||
/*endif*/
|
||||
xmlXIncludeProcess(doc);
|
||||
#if 0
|
||||
#if 1
|
||||
if (!xmlValidateDocument(&valid, doc))
|
||||
{
|
||||
fprintf(stderr, "Invalid document\n");
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t38_non_ecm_buffer_tests.c,v 1.1 2008/08/14 14:06:06 steveu Exp $
|
||||
* $Id: t38_non_ecm_buffer_tests.c,v 1.2 2008/09/02 13:56:10 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -64,7 +64,10 @@ int main(int argc, char *argv[])
|
||||
uint8_t buf[1024];
|
||||
int bit;
|
||||
int n;
|
||||
int log_bits;
|
||||
int i;
|
||||
|
||||
log_bits = FALSE;
|
||||
span_log_init(&logging, SPAN_LOG_FLOW, NULL);
|
||||
span_log_set_protocol(&logging, "Buffer");
|
||||
|
||||
@ -79,10 +82,12 @@ int main(int argc, char *argv[])
|
||||
do
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
}
|
||||
while (bit >= 0);
|
||||
t38_non_ecm_buffer_report_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_input_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_output_status(&buffer, &logging);
|
||||
|
||||
t38_non_ecm_buffer_init(&buffer, TRUE, 0);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
@ -95,10 +100,12 @@ int main(int argc, char *argv[])
|
||||
do
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
}
|
||||
while (bit >= 0);
|
||||
t38_non_ecm_buffer_report_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_input_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_output_status(&buffer, &logging);
|
||||
|
||||
t38_non_ecm_buffer_init(&buffer, TRUE, 400);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
@ -111,10 +118,73 @@ int main(int argc, char *argv[])
|
||||
do
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
}
|
||||
while (bit >= 0);
|
||||
t38_non_ecm_buffer_report_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_input_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_output_status(&buffer, &logging);
|
||||
|
||||
t38_non_ecm_buffer_init(&buffer, TRUE, 400);
|
||||
/* Get some initial bits from an empty buffer. These should be ones */
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (bit != 1)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
/* Now put some zeros into the buffer, but no EOL. We should continue
|
||||
getting ones out. */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 20);
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (bit != 1)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
/* Now add a one, to make an EOL. We should see the zeros come out. */
|
||||
buf[0] = 0x01;
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 1);
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (bit != 0)
|
||||
{
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
/* Now add another line. We should see the first line come out. This means just the
|
||||
eighth bit from now will be a one. */
|
||||
buf[0] = 0x00;
|
||||
buf[4] = 0x01;
|
||||
t38_non_ecm_buffer_inject(&buffer, buf, 5);
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
bit = t38_non_ecm_buffer_get_bit((void *) &buffer);
|
||||
if (log_bits)
|
||||
printf("Rx bit %d - %d\n", n++, bit);
|
||||
if (i != 7 && bit != 0)
|
||||
{
|
||||
printf("Tests failed (%d)\n", i);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
t38_non_ecm_buffer_report_input_status(&buffer, &logging);
|
||||
t38_non_ecm_buffer_report_output_status(&buffer, &logging);
|
||||
|
||||
printf("Tests passed\n");
|
||||
return 0;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: t4_tests.c,v 1.58 2008/08/17 16:25:52 steveu Exp $
|
||||
* $Id: t4_tests.c,v 1.60 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -297,23 +297,23 @@ int main(int argc, char *argv[])
|
||||
t4_rx_start_page(&receive_state);
|
||||
while (fgets(buf, 1024, stdin))
|
||||
{
|
||||
if (sscanf(buf, "HDLC: FCD: 06 %x", &bit) == 1)
|
||||
if (sscanf(buf, "HDLC: FCD: 06 %x", (unsigned int *) &bit) == 1)
|
||||
{
|
||||
/* Useful for breaking up T.38 ECM logs */
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if (sscanf(&buf[18 + 3*i], "%x", &bit) != 1)
|
||||
if (sscanf(&buf[18 + 3*i], "%x", (unsigned int *) &bit) != 1)
|
||||
break;
|
||||
if ((end_of_page = t4_rx_put_byte(&receive_state, bit)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (strlen(buf) > 62 && sscanf(buf + 62, "Rx %d: IFP %x %x", &bit, &bit, &bit) == 3)
|
||||
else if (strlen(buf) > 62 && sscanf(buf + 62, "Rx %*d: IFP %*x %*x") == 3)
|
||||
{
|
||||
/* Useful for breaking up T.38 non-ECM logs */
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if (sscanf(&buf[62 + 29 + 3*i], "%x", &bit) != 1)
|
||||
if (sscanf(&buf[62 + 29 + 3*i], "%x", (unsigned int *) &bit) != 1)
|
||||
break;
|
||||
bit = bit_reverse8(bit);
|
||||
if ((end_of_page = t4_rx_put_byte(&receive_state, bit)))
|
||||
@ -405,7 +405,7 @@ int main(int argc, char *argv[])
|
||||
do
|
||||
{
|
||||
bit = t4_tx_get_bit(&send_state);
|
||||
if (bit == PUTBIT_END_OF_DATA)
|
||||
if (bit == SIG_STATUS_END_OF_DATA)
|
||||
{
|
||||
/* T.6 data does not contain an image termination sequence.
|
||||
T.4 1D and 2D do, and should locate that sequence. */
|
||||
@ -547,7 +547,7 @@ int main(int argc, char *argv[])
|
||||
do
|
||||
{
|
||||
bit = t4_tx_get_bit(&send_state);
|
||||
if (bit == PUTBIT_END_OF_DATA)
|
||||
if (bit == SIG_STATUS_END_OF_DATA)
|
||||
{
|
||||
/* T.6 data does not contain an image termination sequence.
|
||||
T.4 1D and 2D do, and should locate that sequence. */
|
||||
|
@ -22,7 +22,7 @@
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: tsb85_tests.c,v 1.19 2008/08/13 00:11:30 steveu Exp $
|
||||
* $Id: tsb85_tests.c,v 1.22 2008/09/09 15:30:43 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@ -60,6 +60,7 @@
|
||||
#endif
|
||||
|
||||
#include "spandsp.h"
|
||||
#include "spandsp-sim.h"
|
||||
#include "fax_tester.h"
|
||||
|
||||
#define OUTPUT_TIFF_FILE_NAME "tsb85.tif"
|
||||
@ -69,7 +70,6 @@
|
||||
#define SAMPLES_PER_CHUNK 160
|
||||
|
||||
AFfilehandle out_handle;
|
||||
AFfilesetup filesetup;
|
||||
|
||||
int use_receiver_not_ready = FALSE;
|
||||
int test_local_interrupt = FALSE;
|
||||
@ -84,28 +84,122 @@ uint8_t image[1000000];
|
||||
uint8_t awaited[1000];
|
||||
int awaited_len = 0;
|
||||
|
||||
t30_exchanged_info_t expected_rx_info;
|
||||
|
||||
static int next_step(faxtester_state_t *s);
|
||||
|
||||
static int phase_b_handler(t30_state_t *s, void *user_data, int result)
|
||||
{
|
||||
int i;
|
||||
int status;
|
||||
const char *u;
|
||||
|
||||
i = (intptr_t) user_data;
|
||||
status = T30_ERR_OK;
|
||||
if ((u = t30_get_rx_ident(s)))
|
||||
{
|
||||
printf("%d: Phase B: remote ident '%s'\n", i, u);
|
||||
if (expected_rx_info.ident[0] && strcmp(expected_rx_info.ident, u))
|
||||
{
|
||||
printf("%d: Phase B: remote ident incorrect! - expected '%s'\n", i, expected_rx_info.ident);
|
||||
status = T30_ERR_IDENT_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expected_rx_info.ident[0])
|
||||
{
|
||||
printf("%d: Phase B: remote ident missing!\n", i);
|
||||
status = T30_ERR_IDENT_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
if ((u = t30_get_rx_sub_address(s)))
|
||||
{
|
||||
printf("%d: Phase B: remote sub-address '%s'\n", i, u);
|
||||
if (expected_rx_info.sub_address[0] && strcmp(expected_rx_info.sub_address, u))
|
||||
{
|
||||
printf("%d: Phase B: remote sub-address incorrect! - expected '%s'\n", i, expected_rx_info.sub_address);
|
||||
status = T30_ERR_SUB_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expected_rx_info.sub_address[0])
|
||||
{
|
||||
printf("%d: Phase B: remote sub-address missing!\n", i);
|
||||
status = T30_ERR_SUB_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
if ((u = t30_get_rx_polled_sub_address(s)))
|
||||
{
|
||||
printf("%d: Phase B: remote polled sub-address '%s'\n", i, u);
|
||||
if (expected_rx_info.polled_sub_address[0] && strcmp(expected_rx_info.polled_sub_address, u))
|
||||
{
|
||||
printf("%d: Phase B: remote polled sub-address incorrect! - expected '%s'\n", i, expected_rx_info.polled_sub_address);
|
||||
status = T30_ERR_PSA_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expected_rx_info.polled_sub_address[0])
|
||||
{
|
||||
printf("%d: Phase B: remote polled sub-address missing!\n", i);
|
||||
status = T30_ERR_PSA_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
if ((u = t30_get_rx_selective_polling_address(s)))
|
||||
{
|
||||
printf("%d: Phase B: remote selective polling address '%s'\n", i, u);
|
||||
if (expected_rx_info.selective_polling_address[0] && strcmp(expected_rx_info.selective_polling_address, u))
|
||||
{
|
||||
printf("%d: Phase B: remote selective polling address incorrect! - expected '%s'\n", i, expected_rx_info.selective_polling_address);
|
||||
status = T30_ERR_SEP_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expected_rx_info.selective_polling_address[0])
|
||||
{
|
||||
printf("%d: Phase B: remote selective polling address missing!\n", i);
|
||||
status = T30_ERR_SEP_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
if ((u = t30_get_rx_sender_ident(s)))
|
||||
{
|
||||
printf("%d: Phase B: remote sender ident '%s'\n", i, u);
|
||||
if (expected_rx_info.sender_ident[0] && strcmp(expected_rx_info.sender_ident, u))
|
||||
{
|
||||
printf("%d: Phase B: remote sender ident incorrect! - expected '%s'\n", i, expected_rx_info.sender_ident);
|
||||
status = T30_ERR_SID_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expected_rx_info.sender_ident[0])
|
||||
{
|
||||
printf("%d: Phase B: remote sender ident missing!\n", i);
|
||||
status = T30_ERR_SID_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
if ((u = t30_get_rx_password(s)))
|
||||
{
|
||||
printf("%d: Phase B: remote password '%s'\n", i, u);
|
||||
if (expected_rx_info.password[0] && strcmp(expected_rx_info.password, u))
|
||||
{
|
||||
printf("%d: Phase B: remote password incorrect! - expected '%s'\n", i, expected_rx_info.password);
|
||||
status = T30_ERR_PWD_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expected_rx_info.password[0])
|
||||
{
|
||||
printf("%d: Phase B: remote password missing!\n", i);
|
||||
status = T30_ERR_PWD_UNACCEPTABLE;
|
||||
}
|
||||
}
|
||||
printf("%d: Phase B handler on channel %d - (0x%X) %s\n", i, i, result, t30_frametype(result));
|
||||
return T30_ERR_OK;
|
||||
return status;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@ -184,7 +278,8 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result)
|
||||
printf("%d: Phase E: longest bad row run %d\n", i, t.longest_bad_row_run);
|
||||
printf("%d: Phase E: coding method %s\n", i, t4_encoding_to_str(t.encoding));
|
||||
printf("%d: Phase E: image size %d bytes\n", i, t.image_size);
|
||||
//printf("%d: Phase E: local ident '%s'\n", i, info->ident);
|
||||
if ((u = t30_get_tx_ident(s)))
|
||||
printf("%d: Phase E: local ident '%s'\n", i, u);
|
||||
if ((u = t30_get_rx_ident(s)))
|
||||
printf("%d: Phase E: remote ident '%s'\n", i, u);
|
||||
if ((u = t30_get_rx_country(s)))
|
||||
@ -207,10 +302,11 @@ static void t30_real_time_frame_handler(t30_state_t *s,
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("T.30: Real time frame handler - %s, %s, length = %d\n",
|
||||
(direction) ? "line->T.30" : "T.30->line",
|
||||
t30_frametype(msg[2]),
|
||||
len);
|
||||
fprintf(stderr,
|
||||
"T.30: Real time frame handler - %s, %s, length = %d\n",
|
||||
(direction) ? "line->T.30" : "T.30->line",
|
||||
t30_frametype(msg[2]),
|
||||
len);
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -220,7 +316,7 @@ static int document_handler(t30_state_t *s, void *user_data, int event)
|
||||
int i;
|
||||
|
||||
i = (intptr_t) user_data;
|
||||
printf("%d: Document handler on channel %d - event %d\n", i, i, event);
|
||||
fprintf(stderr, "%d: Document handler on channel %d - event %d\n", i, i, event);
|
||||
return FALSE;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -237,11 +333,12 @@ static void faxtester_real_time_frame_handler(faxtester_state_t *s,
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Real time frame handler - %s, %s, length = %d\n",
|
||||
(direction) ? "line->tester" : "tester->line",
|
||||
t30_frametype(msg[2]),
|
||||
len);
|
||||
if (direction && msg[1] == 0x13)
|
||||
fprintf(stderr,
|
||||
"TST: Real time frame handler - %s, %s, length = %d\n",
|
||||
(direction) ? "line->tester" : "tester->line",
|
||||
t30_frametype(msg[2]),
|
||||
len);
|
||||
if (direction && msg[1] == awaited[1])
|
||||
{
|
||||
if ((awaited_len >= 0 && len != abs(awaited_len))
|
||||
||
|
||||
@ -249,12 +346,12 @@ static void faxtester_real_time_frame_handler(faxtester_state_t *s,
|
||||
||
|
||||
memcmp(msg, awaited, abs(awaited_len)) != 0)
|
||||
{
|
||||
span_log_buf(&s->logging, SPAN_LOG_FLOW, "Expected", awaited, awaited_len);
|
||||
span_log_buf(&s->logging, SPAN_LOG_FLOW, "Expected", awaited, abs(awaited_len));
|
||||
span_log_buf(&s->logging, SPAN_LOG_FLOW, "Received", msg, len);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
if (msg[1] == 0x13)
|
||||
if (msg[1] == awaited[1])
|
||||
next_step(s);
|
||||
}
|
||||
}
|
||||
@ -280,13 +377,17 @@ static void fax_prepare(void)
|
||||
t30 = fax_get_t30_state(&fax);
|
||||
fax_set_transmit_on_idle(&fax, TRUE);
|
||||
fax_set_tep_mode(&fax, TRUE);
|
||||
#if 0
|
||||
t30_set_tx_ident(t30, "1234567890");
|
||||
t30_set_tx_sub_address(t30, "Sub-address");
|
||||
t30_set_tx_sender_ident(t30, "Sender ID");
|
||||
t30_set_tx_password(t30, "Password");
|
||||
t30_set_tx_polled_sub_address(t30, "Polled sub-address");
|
||||
t30_set_tx_selective_polling_address(t30, "Sel polling address");
|
||||
t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12);
|
||||
#endif
|
||||
t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSF\x00", 16);
|
||||
//t30_set_tx_nss(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSS\x00", 16);
|
||||
t30_set_tx_nsc(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp NSC\x00", 16);
|
||||
t30_set_ecm_capability(t30, TRUE);
|
||||
t30_set_supported_t30_features(t30,
|
||||
T30_SUPPORT_IDENTIFICATION
|
||||
@ -531,6 +632,7 @@ static int next_step(faxtester_state_t *s)
|
||||
{
|
||||
/* Add a bit of waiting at the end, to ensure everything gets flushed through,
|
||||
any timers can expire, etc. */
|
||||
faxtester_set_timeout(s, -1);
|
||||
faxtester_set_rx_type(s, T30_MODEM_NONE, 0, FALSE, FALSE);
|
||||
faxtester_set_tx_type(s, T30_MODEM_PAUSE, 0, 120000, FALSE);
|
||||
s->final_delayed = TRUE;
|
||||
@ -628,7 +730,24 @@ static int next_step(faxtester_state_t *s)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Unrecognised modem\n");
|
||||
}
|
||||
}
|
||||
if (strcasecmp((const char *) type, "CNG") == 0)
|
||||
|
||||
if (strcasecmp((const char *) type, "SET") == 0)
|
||||
{
|
||||
if (strcasecmp((const char *) tag, "IDENT") == 0)
|
||||
strcpy(expected_rx_info.ident, (const char *) value);
|
||||
else if (strcasecmp((const char *) tag, "SUB") == 0)
|
||||
strcpy(expected_rx_info.sub_address, (const char *) value);
|
||||
else if (strcasecmp((const char *) tag, "SEP") == 0)
|
||||
strcpy(expected_rx_info.selective_polling_address, (const char *) value);
|
||||
else if (strcasecmp((const char *) tag, "PSA") == 0)
|
||||
strcpy(expected_rx_info.polled_sub_address, (const char *) value);
|
||||
else if (strcasecmp((const char *) tag, "SID") == 0)
|
||||
strcpy(expected_rx_info.sender_ident, (const char *) value);
|
||||
else if (strcasecmp((const char *) tag, "PWD") == 0)
|
||||
strcpy(expected_rx_info.password, (const char *) value);
|
||||
return 0;
|
||||
}
|
||||
else if (strcasecmp((const char *) type, "CNG") == 0)
|
||||
{
|
||||
/* Look for CNG */
|
||||
faxtester_set_rx_type(s, T30_MODEM_CNG, 0, FALSE, FALSE);
|
||||
@ -715,7 +834,33 @@ static int next_step(faxtester_state_t *s)
|
||||
}
|
||||
}
|
||||
|
||||
if (strcasecmp((const char *) type, "CALL") == 0)
|
||||
if (strcasecmp((const char *) type, "SET") == 0)
|
||||
{
|
||||
t30 = fax_get_t30_state(&fax);
|
||||
if (strcasecmp((const char *) tag, "IDENT") == 0)
|
||||
t30_set_tx_ident(t30, (const char *) value);
|
||||
else if (strcasecmp((const char *) tag, "SUB") == 0)
|
||||
t30_set_tx_sub_address(t30, (const char *) value);
|
||||
else if (strcasecmp((const char *) tag, "SEP") == 0)
|
||||
t30_set_tx_selective_polling_address(t30, (const char *) value);
|
||||
else if (strcasecmp((const char *) tag, "PSA") == 0)
|
||||
t30_set_tx_polled_sub_address(t30, (const char *) value);
|
||||
else if (strcasecmp((const char *) tag, "SID") == 0)
|
||||
t30_set_tx_sender_ident(t30, (const char *) value);
|
||||
else if (strcasecmp((const char *) tag, "PWD") == 0)
|
||||
t30_set_tx_password(t30, (const char *) value);
|
||||
else if (strcasecmp((const char *) tag, "RXFILE") == 0)
|
||||
{
|
||||
if (value)
|
||||
t30_set_rx_file(t30, (const char *) value, -1);
|
||||
else
|
||||
t30_set_rx_file(t30, output_tiff_file_name, -1);
|
||||
}
|
||||
else if (strcasecmp((const char *) tag, "TXFILE") == 0)
|
||||
t30_set_tx_file(t30, (const char *) value, -1, -1);
|
||||
return 0;
|
||||
}
|
||||
else if (strcasecmp((const char *) type, "CALL") == 0)
|
||||
{
|
||||
fax_init(&fax, FALSE);
|
||||
fax_prepare();
|
||||
@ -898,18 +1043,7 @@ static void exchange(faxtester_state_t *s)
|
||||
|
||||
if (log_audio)
|
||||
{
|
||||
if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP)
|
||||
{
|
||||
fprintf(stderr, " Failed to create file setup\n");
|
||||
exit(2);
|
||||
}
|
||||
/*endif*/
|
||||
afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
|
||||
afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE);
|
||||
afInitFileFormat(filesetup, AF_FILE_WAVE);
|
||||
afInitChannels(filesetup, AF_DEFAULT_TRACK, 2);
|
||||
|
||||
if ((out_handle = afOpenFile(OUTPUT_FILE_NAME_WAVE, "w", filesetup)) == AF_NULL_FILEHANDLE)
|
||||
if ((out_handle = afOpenFile_telephony_write(OUTPUT_FILE_NAME_WAVE, 2)) == AF_NULL_FILEHANDLE)
|
||||
{
|
||||
fprintf(stderr, " Cannot create wave file '%s'\n", OUTPUT_FILE_NAME_WAVE);
|
||||
exit(2);
|
||||
@ -975,7 +1109,6 @@ static void exchange(faxtester_state_t *s)
|
||||
exit(2);
|
||||
}
|
||||
/*endif*/
|
||||
afFreeFileSetup(filesetup);
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
@ -1014,22 +1147,21 @@ static int get_test_set(faxtester_state_t *s, const char *test_file, const char
|
||||
xmlDocPtr doc;
|
||||
xmlNsPtr ns;
|
||||
xmlNodePtr cur;
|
||||
#if 0
|
||||
#if 1
|
||||
xmlValidCtxt valid;
|
||||
#endif
|
||||
|
||||
ns = NULL;
|
||||
xmlKeepBlanksDefault(0);
|
||||
xmlCleanupParser();
|
||||
doc = xmlParseFile(test_file);
|
||||
if (doc == NULL)
|
||||
if ((doc = xmlParseFile(test_file)) == NULL)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "No document\n");
|
||||
exit(2);
|
||||
}
|
||||
/*endif*/
|
||||
xmlXIncludeProcess(doc);
|
||||
#if 0
|
||||
#if 1
|
||||
if (!xmlValidateDocument(&valid, doc))
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Invalid document\n");
|
||||
@ -1091,6 +1223,7 @@ int main(int argc, char *argv[])
|
||||
test_name = argv[1];
|
||||
|
||||
faxtester_init(&state, TRUE);
|
||||
memset(&expected_rx_info, 0, sizeof(expected_rx_info));
|
||||
span_log_set_level(&state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
|
||||
span_log_set_tag(&state.logging, "B");
|
||||
get_test_set(&state, "../spandsp/tsb85.xml", test_name);
|
||||
|
@ -15,7 +15,7 @@
|
||||
# License along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id: tsb85_tests.sh,v 1.3 2008/08/04 14:03:17 steveu Exp $
|
||||
# $Id: tsb85_tests.sh,v 1.4 2008/09/09 15:30:43 steveu Exp $
|
||||
#
|
||||
|
||||
run_tsb85_test()
|
||||
@ -36,7 +36,7 @@ for TEST in MRGN01 MRGN02 MRGN03 MRGN04 MRGN05 MRGN06a MRGN06b MRGN07 MRGN08 ; d
|
||||
done
|
||||
|
||||
#for TEST in MRGN09 MRGN10 MRGN11 MRGN12 MRGN13 MRGN14 MRGN15 MRGN16 MRGN17 ; do
|
||||
for TEST in MRGN09 MRGN10 MRGN11 MRGN12 MRGN13 MRGN15 MRGN17 ; do
|
||||
for TEST in MRGN09 MRGN10 MRGN11 MRGN12 MRGN13 MRGN15 ; do
|
||||
run_tsb85_test
|
||||
done
|
||||
|
||||
@ -54,7 +54,7 @@ for TEST in MRGX02 MRGX04 MRGX06 MRGX07 MRGX08 ; do
|
||||
done
|
||||
|
||||
#for TEST in MRGX09 MRGX10 MRGX11 MRGX12 MRGX13 MRGX14 MRGX15 ; do
|
||||
for TEST in MRGX09 MRGX10 MRGX11 ; do
|
||||
for TEST in MRGX09 MRGX11 ; do
|
||||
run_tsb85_test
|
||||
done
|
||||
|
||||
@ -91,14 +91,14 @@ done
|
||||
#done
|
||||
|
||||
#for TEST in MTGX17 MTGX18 MTGX19 MTGX20 MTGX21 MTGX22 MTGX23 ; do
|
||||
# run_tsb85_test
|
||||
#done
|
||||
|
||||
#for TEST in MRGP01 MRGP02 MRGP03 MRGP04 MRGP05 MRGP06 MRGP07 MRGP08 ; do
|
||||
for TEST in MRGP03 MRGP04 MRGP05 ; do
|
||||
for TEST in MTGX18 MTGX19 MTGX20 MTGX21 MTGX22 MTGX23 ; do
|
||||
run_tsb85_test
|
||||
done
|
||||
|
||||
#for TEST in ORGP09 ORGP10 ; do
|
||||
# run_tsb85_test
|
||||
#done
|
||||
for TEST in MRGP01 MRGP02 MRGP03 MRGP04 MRGP05 MRGP06 MRGP07 MRGP08 ; do
|
||||
run_tsb85_test
|
||||
done
|
||||
|
||||
for TEST in ORGP09 ORGP10 ; do
|
||||
run_tsb85_test
|
||||
done
|
||||
|
@ -23,7 +23,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v17_tests.c,v 1.87 2008/08/29 09:28:13 steveu Exp $
|
||||
* $Id: v17_tests.c,v 1.90 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page v17_tests_page V.17 modem tests
|
||||
@ -141,32 +141,16 @@ static int v17_rx_status(void *user_data, int status)
|
||||
int len;
|
||||
complexf_t *coeffs;
|
||||
|
||||
printf("V.17 rx status is %d\n", status);
|
||||
printf("V.17 rx status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
rx = (v17_rx_state_t *) user_data;
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
printf("Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
printf("Training in progress\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
printf("Training succeeded\n");
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
len = v17_rx_equalizer_state(rx, &coeffs);
|
||||
printf("Equalizer:\n");
|
||||
for (i = 0; i < len; i++)
|
||||
printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i]));
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
printf("Carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
printf("Carrier down\n");
|
||||
break;
|
||||
default:
|
||||
printf("Eh! - %d\n", status);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -192,18 +176,7 @@ static void v17putbit(void *user_data, int bit)
|
||||
|
||||
static int v17_tx_status(void *user_data, int status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case MODEM_TX_STATUS_DATA_EXHAUSTED:
|
||||
printf("V.17 tx data exhausted\n");
|
||||
break;
|
||||
case MODEM_TX_STATUS_SHUTDOWN_COMPLETE:
|
||||
printf("V.17 tx shutdown complete\n");
|
||||
break;
|
||||
default:
|
||||
printf("V.17 tx status is %d\n", status);
|
||||
break;
|
||||
}
|
||||
printf("V.17 tx status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -460,8 +433,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* Note that we might get a few bad bits as the carrier shuts down. */
|
||||
bert_result(&bert, &bert_results);
|
||||
fprintf(stderr, "Final result %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
fprintf(stderr, "Last report %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
|
||||
fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
|
||||
/* See if bit errors are appearing yet. Also check we are getting enough bits out of the receiver. The last regular report
|
||||
should be error free, though the final report will generally contain bits errors as the carrier was dying. The total
|
||||
number of bits out of the receiver should be at least the number we sent. Also, since BERT sync should have occurred
|
||||
@ -516,8 +489,8 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
bert_result(&bert, &bert_results);
|
||||
fprintf(stderr, "At completion:\n");
|
||||
fprintf(stderr, "Final result %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
fprintf(stderr, "Last report %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
|
||||
fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
|
||||
one_way_line_model_release(line_model);
|
||||
|
||||
if (signal_level > -43)
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v22bis_tests.c,v 1.51 2008/08/16 14:59:50 steveu Exp $
|
||||
* $Id: v22bis_tests.c,v 1.52 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page v22bis_tests_page V.22bis modem tests
|
||||
@ -108,30 +108,15 @@ static void v22bis_putbit(void *user_data, int bit)
|
||||
if (bit < 0)
|
||||
{
|
||||
/* Special conditions */
|
||||
printf("V.22bis rx status is %s (%d)\n", signal_status_to_str(bit), bit);
|
||||
switch (bit)
|
||||
{
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
printf("Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
printf("Training in progress\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
printf("Training succeeded\n");
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
len = v22bis_equalizer_state(s, &coeffs);
|
||||
printf("Equalizer:\n");
|
||||
for (i = 0; i < len; i++)
|
||||
printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i]));
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
printf("Carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
printf("Carrier down\n");
|
||||
break;
|
||||
default:
|
||||
printf("Eh! - %d\n", bit);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v27ter_tests.c,v 1.91 2008/08/29 09:28:13 steveu Exp $
|
||||
* $Id: v27ter_tests.c,v 1.93 2008/09/07 06:39:52 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page v27ter_tests_page V.27ter modem tests
|
||||
@ -132,28 +132,7 @@ static void reporter(void *user_data, int reason, bert_results_t *results)
|
||||
|
||||
static int v27ter_rx_status(void *user_data, int status)
|
||||
{
|
||||
printf("V.27ter rx status is %d\n", status);
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
printf("Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
printf("Training in progress\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
printf("Training succeeded\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
printf("Carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
printf("Carrier down\n");
|
||||
break;
|
||||
default:
|
||||
printf("Eh! - %d\n", status);
|
||||
break;
|
||||
}
|
||||
printf("V.27ter rx status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -174,18 +153,7 @@ static void v27terputbit(void *user_data, int bit)
|
||||
|
||||
static int v27ter_tx_status(void *user_data, int status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case MODEM_TX_STATUS_DATA_EXHAUSTED:
|
||||
printf("V.27ter tx data exhausted\n");
|
||||
break;
|
||||
case MODEM_TX_STATUS_SHUTDOWN_COMPLETE:
|
||||
printf("V.27ter tx shutdown complete\n");
|
||||
break;
|
||||
default:
|
||||
printf("V.27ter tx status is %d\n", status);
|
||||
break;
|
||||
}
|
||||
printf("V.27ter tx status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -457,8 +425,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* Note that we might get a few bad bits as the carrier shuts down. */
|
||||
bert_result(&bert, &bert_results);
|
||||
fprintf(stderr, "Final result %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
fprintf(stderr, "Last report %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
|
||||
fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
|
||||
/* See if bit errors are appearing yet. Also check we are getting enough bits out of the receiver. The last regular report
|
||||
should be error free, though the final report will generally contain bits errors as the carrier was dying. The total
|
||||
number of bits out of the receiver should be at least the number we sent. Also, since BERT sync should have occurred
|
||||
@ -506,15 +474,13 @@ int main(int argc, char *argv[])
|
||||
line_model_monitor_line_spectrum_update(amp, samples);
|
||||
#endif
|
||||
v27ter_rx(&rx, amp, samples);
|
||||
if (decode_test_file == NULL && block%500 == 0)
|
||||
printf("Noise level is %d\n", noise_level);
|
||||
}
|
||||
if (!decode_test_file)
|
||||
{
|
||||
bert_result(&bert, &bert_results);
|
||||
fprintf(stderr, "At completion:\n");
|
||||
fprintf(stderr, "Final result %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
fprintf(stderr, "Last report %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
|
||||
fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
|
||||
one_way_line_model_release(line_model);
|
||||
if (signal_level > -43)
|
||||
{
|
||||
|
@ -22,7 +22,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: v29_tests.c,v 1.102 2008/08/29 09:28:13 steveu Exp $
|
||||
* $Id: v29_tests.c,v 1.106 2008/09/07 12:45:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \page v29_tests_page V.29 modem tests
|
||||
@ -134,33 +134,29 @@ static int v29_rx_status(void *user_data, int status)
|
||||
v29_rx_state_t *rx;
|
||||
int i;
|
||||
int len;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexi16_t *coeffs;
|
||||
#else
|
||||
complexf_t *coeffs;
|
||||
#endif
|
||||
|
||||
printf("V.29 rx status is %d\n", status);
|
||||
printf("V.29 rx status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
rx = (v29_rx_state_t *) user_data;
|
||||
switch (status)
|
||||
{
|
||||
case PUTBIT_TRAINING_FAILED:
|
||||
printf("Training failed\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_IN_PROGRESS:
|
||||
printf("Training in progress\n");
|
||||
break;
|
||||
case PUTBIT_TRAINING_SUCCEEDED:
|
||||
case SIG_STATUS_TRAINING_SUCCEEDED:
|
||||
printf("Training succeeded\n");
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
len = v29_rx_equalizer_state(rx, &coeffs);
|
||||
printf("Equalizer:\n");
|
||||
for (i = 0; i < len; i++)
|
||||
printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/4096.0f, coeffs[i].im/4096.0f);
|
||||
#else
|
||||
len = v29_rx_equalizer_state(rx, &coeffs);
|
||||
printf("Equalizer:\n");
|
||||
for (i = 0; i < len; i++)
|
||||
printf("%3d (%15.5f, %15.5f) -> %15.5f\n", i, coeffs[i].re, coeffs[i].im, powerf(&coeffs[i]));
|
||||
break;
|
||||
case PUTBIT_CARRIER_UP:
|
||||
printf("Carrier up\n");
|
||||
break;
|
||||
case PUTBIT_CARRIER_DOWN:
|
||||
printf("Carrier down\n");
|
||||
break;
|
||||
default:
|
||||
printf("Eh! - %d\n", status);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -187,18 +183,7 @@ static void v29putbit(void *user_data, int bit)
|
||||
|
||||
static int v29_tx_status(void *user_data, int status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case MODEM_TX_STATUS_DATA_EXHAUSTED:
|
||||
printf("V.29 tx data exhausted\n");
|
||||
break;
|
||||
case MODEM_TX_STATUS_SHUTDOWN_COMPLETE:
|
||||
printf("V.29 tx shutdown complete\n");
|
||||
break;
|
||||
default:
|
||||
printf("V.29 tx status is %d\n", status);
|
||||
break;
|
||||
}
|
||||
printf("V.29 tx status is %s (%d)\n", signal_status_to_str(status), status);
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -213,7 +198,11 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexi16_t *coeffs;
|
||||
#else
|
||||
complexf_t *coeffs;
|
||||
#endif
|
||||
float fpower;
|
||||
v29_rx_state_t *rx;
|
||||
static float smooth_power = 0.0f;
|
||||
@ -249,6 +238,16 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex
|
||||
symbol_no++;
|
||||
if (--update_interval <= 0)
|
||||
{
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
len = v29_rx_equalizer_state(rx, &coeffs);
|
||||
printf("Equalizer A:\n");
|
||||
for (i = 0; i < len; i++)
|
||||
printf("%3d (%15.5f, %15.5f)\n", i, coeffs[i].re/4096.0f, coeffs[i].im/4096.0f);
|
||||
#if defined(ENABLE_GUI)
|
||||
if (use_gui)
|
||||
qam_monitor_update_int_equalizer(qam_monitor, coeffs, len);
|
||||
#endif
|
||||
#else
|
||||
len = v29_rx_equalizer_state(rx, &coeffs);
|
||||
printf("Equalizer A:\n");
|
||||
for (i = 0; i < len; i++)
|
||||
@ -256,6 +255,7 @@ static void qam_report(void *user_data, const complexf_t *constel, const complex
|
||||
#if defined(ENABLE_GUI)
|
||||
if (use_gui)
|
||||
qam_monitor_update_equalizer(qam_monitor, coeffs, len);
|
||||
#endif
|
||||
#endif
|
||||
update_interval = 100;
|
||||
}
|
||||
@ -451,8 +451,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* Note that we might get a few bad bits as the carrier shuts down. */
|
||||
bert_result(&bert, &bert_results);
|
||||
fprintf(stderr, "Final result %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
fprintf(stderr, "Last report %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
|
||||
fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
|
||||
/* See if bit errors are appearing yet. Also check we are getting enough bits out of the receiver. The last regular report
|
||||
should be error free, though the final report will generally contain bits errors as the carrier was dying. The total
|
||||
number of bits out of the receiver should be at least the number we sent. Also, since BERT sync should have occurred
|
||||
@ -500,15 +500,13 @@ int main(int argc, char *argv[])
|
||||
line_model_monitor_line_spectrum_update(amp, samples);
|
||||
#endif
|
||||
v29_rx(&rx, amp, samples);
|
||||
if (decode_test_file == NULL && block%500 == 0)
|
||||
printf("Noise level is %d\n", noise_level);
|
||||
}
|
||||
if (!decode_test_file)
|
||||
{
|
||||
bert_result(&bert, &bert_results);
|
||||
fprintf(stderr, "At completion:\n");
|
||||
fprintf(stderr, "Final result %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
fprintf(stderr, "Last report %ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
|
||||
fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
|
||||
fprintf(stderr, "Last report %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
|
||||
one_way_line_model_release(line_model);
|
||||
|
||||
if (signal_level > -43)
|
||||
|
Loading…
x
Reference in New Issue
Block a user