New sound API, more sensible and support for echo cancellation's
authorRick van Rein <rick@openfortress.nl>
Fri, 20 Jan 2012 15:20:41 +0000 (16:20 +0100)
committerRick van Rein <rick@openfortress.nl>
Fri, 20 Jan 2012 15:22:31 +0000 (16:22 +0100)
accurate timing requirements.  Improved RTT.  Added L8/L16 codecs.

21 files changed:
Makefile
TODO
include/0cpm/cons.h
include/bottom/grandstream.h
include/bottom/tic55x.h
include/tic55x/stdbool.h
src/codec/l8l16.c
src/codec/rtt/Makefile.desktop
src/codec/rtt/README
src/codec/rtt/desktop.c
src/codec/rtt/recvkeys.c
src/codec/rtt/uac.sipp [new file with mode: 0644]
src/codec/rtt/uas-passive.sipp [new file with mode: 0644]
src/codec/rtt/user-display.sh [new file with mode: 0755]
src/codec/wrap.c
src/driver/tic55x/grandstream-bt20x.c
src/driver/tic55x/linker.cmd
src/function/Kconfig
src/function/develtest/echo.c
src/target/Kconfig
src/target/Kconfig.grandstream

index 8920d0b..607d93f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -113,7 +113,11 @@ bin/bottom.o: $(objs-bottom-y)
 # Create a "tags" file for easy Vim navigation
 #
 tags: src/net/6bed4.c
-       ctags $(objs-top-kernel-y:.o=.c) $(objs-top-net-y:.o=.c) $(objs-top-phone-y:.o=.c) $(objs-bottom-y:.o=.c) include/0cpm/*.h include/config.h
+       # [ ! -f src/driver/tic55x/isrmap.c ] && touch src/driver/tic55x/isrmap.c
+       # ctags $(objs-top-kernel-y:.o=.c) $(objs-top-net-y:.o=.c) $(objs-top-phone-y:.o=.c) include/0cpm/*.h include/config.h $(objs-bottom-y:.o=.c)
+       # [ ! -s src/driver/tic55x/isrmap.c ] && rm src/driver/tic55x/isrmap.c
+       rm -f tags
+       for f in $(objs-top-kernel-y:.o=.c) $(objs-top-net-y:.o=.c) $(objs-top-phone-y:.o=.c) include/0cpm/*.h include/config.h $(objs-bottom-y:.o=.c); do if [ -s "$$f" ] ; then ctags --append=yes "$$f" ; fi ; done
 
 #
 # Create API documentation with doxygen
diff --git a/TODO b/TODO
index 8c65bc6..129e940 100644 (file)
--- a/TODO
+++ b/TODO
@@ -50,6 +50,16 @@ look at:
 
 * RTT handling:
    - consider replacing the call to rtt_recv_keys() with a textapp wakeup
+   - show RTT on the display
 
 * Transcoding: Now supported in spandsp (for G.711) -- this can go.
 
+* T.38 fax support:
+   - exchange TIFF in fax-usable formats
+   - couple or drop logging
+   - link T.38 to the RTP stack
+   - link T.38 to the TFTP stack
+   - show on the interface what is going on
+   - figure out how much code is added for T.38 -- might be quite a lot
+
+
index 7c4173f..cba4233 100644 (file)
@@ -49,6 +49,6 @@
                bottom_console_vprintf (fmt, argh);
                va_end (argh);
        }
-#endif
-
 #endif /* CONFIG_FUNCTION_NETCONSOLE */
+
+#endif /* HEADER_CONSOLE */
index a884edf..07f9ca0 100644 (file)
 #define NEED_KBD_SCANNER_DURING_KEYPRESS 1
 
 
-inline bool bottom_soundchannel_acceptable_samplerate (uint8_t chan, uint32_t samplerate) {
+static inline bool bottom_soundchannel_acceptable_samplerate (uint8_t chan, uint32_t samplerate) {
        return (samplerate >= 1875) && (samplerate <= 52000);
 }
 
-inline bool bottom_soundchannel_preferred_samplerate (uint8_t chan, uint32_t samplerate) {
+static inline bool bottom_soundchannel_preferred_samplerate (uint8_t chan, uint32_t samplerate) {
        return bottom_acceptable_samplerate (chan, samplerate)
                && ( ( ( 30720000 / 16 ) % ( 1 * 2 * samplerate)) == 0);
 }
index 4450ab2..2a30fde 100644 (file)
@@ -86,6 +86,10 @@ typedef uint32_t timing_t;
 #pragma CODE_SECTION(netinput, ".text_fast");
 
 
+/* Optimising included codecs: Speex, SpanDSP */
+#define CONFIG_TI_C55X 1
+
+
 /* Following definitions are only available if BOTTOM is defined */
 
 #ifdef BOTTOM
index be5731d..e8d21dd 100644 (file)
  */
 
 
+#ifndef HEADER_BOOL
+#define HEADER_BOOL
+
 typedef enum {
        false = 0,
        true  = 1
 } bool;
+
+#endif
index e9b9cda..327cf5b 100644 (file)
 
 void l8_decode (struct codec *hdl, int16_t *pcm, uint16_t *pcmlen, uint8_t *pkt, uint16_t *pktlen) {
        while ((*pktlen >= 1) && (*pcmlen >= 1)) {
-               // Note: The 0xff masks away bits from 16-bit DSPs like tic55x
-               *pcm++ = (((*pkt++) & 0xff) ^ 0x80) << 8;
-               *pcmlen--;
-               *pktlen--;
+               // Note: The 0x00ff masks away extra bits from 16-bit DSPs like tic55x
+               *pcm++ = ((((uint16_t) *pkt++) & 0x00ff) ^ 0x0080) << 8;
+               (*pcmlen) --;
+               (*pktlen) --;
        }
 }
 
 void l8_encode (struct codec *hdl, int16_t *pcm, uint16_t *pcmlen, uint8_t *pkt, uint16_t *pktlen) {
        while ((*pktlen >= 1) && (*pcmlen >= 1)) {
-               // Note: The 0xff masks away bits from 16-bit DSPs like tic55x
+               // Note: The 0xff masks away extra bits from 16-bit DSPs like tic55x
                *pkt++ = (((*pcm++) >> 8) ^ 0x80) & 0xff;
-               *pcmlen--;
-               *pktlen--;
+               (*pcmlen) --;
+               (*pktlen) --;
        }
 }
 
 void l16_decode (struct codec *hdl, int16_t *pcm, uint16_t *pcmlen, uint8_t *pkt, uint16_t *pktlen) {
        while ((*pktlen >= 2) && (*pcmlen >= 1)) {
-               // Note: The 0xff masks away bits from 16-bit DSPs like tic55x
-               *pcm++ = (int16_t) (((*pkt++) << 8) | ((*pkt++) & 0xff));
-               *pcmlen--;
-               *pktlen -= 2;
+               // Note: The 0xff masks away extra bits from 16-bit DSPs like tic55x
+               *pcm++ = (int16_t) ((((uint16_t) *pkt++) << 8) | ((*pkt++) & 0xff));
+               (*pcmlen) --;
+               (*pktlen) -= 2;
        }
 }
 
 void l16_encode (struct codec *hdl, int16_t *pcm, uint16_t *pcmlen, uint8_t *pkt, uint16_t *pktlen) {
        while ((*pktlen >= 2) && (*pcmlen >= 1)) {
-               // Note: The 0xff masks away bits from 16-bit DSPs like tic55x
+               // Note: The 0xff masks away extra bits from 16-bit DSPs like tic55x
                *pkt++ = ((*pcm) >> 8) & 0xff;
                *pkt++ = (*pcm++) & 0xff;
-               *pcmlen--;
-               *pktlen -= 2;
+               (*pcmlen) --;
+               (*pktlen) -= 2;
        }
 }
 
index 60d7f9e..db018f4 100644 (file)
@@ -1,10 +1,10 @@
 TARGET=rtt_desktop_test
 OBJS=recvkeys.o sendkeys.o desktop.o
 
-# CFLAGS=-m32 -L.
-CFLAGS=-m64
+# CFLAGS=-m32 -L. -DTODO_WAKEUP_TEXTSHOW_PROCESS
+CFLAGS=-m64 -DTODO_WAKEUP_TEXTSHOW_PROCESS
 
-# CFLAGS+=-ggdb3
+CFLAGS+=-ggdb3
 
 all: tags $(TARGET)
 
@@ -21,3 +21,6 @@ $(TARGET): $(OBJS)
 
 tags:
        ctags *.c
+
+rtp-setup-pipe:
+       mknod rtp-setup-pipe p
index 88886d9..c4c7037 100644 (file)
@@ -66,6 +66,35 @@ a quick IPv6 tunnel, you can use the 6bed4 mechanism, described on
 http://devel.0cpm.org/6bed4/
 
 
+Test with SIP using SIPP
+------------------------
+
+Some tests warrant a simple SIP client, for example compliance testing.  This
+can be achieved using SIPP, a tool that can send and receive scripted SIP
+messages.  Upon reception, it can also run commands.
+
+Use the uac.sipp or the uas-passive.sipp script.  These will send the RTP
+coordinates to a named pipe (./rtp-setip-pipe) that is created automatically
+and then listened to by the ./user-display.sh script.  As soon as an RTP
+setup is constructed by SIPP, it will send it to the pipe, and the script
+will start the RTT desktop test tool with the RTP parameters.
+
+The commands to run such tests are::
+
+       sipp -i [2001:db8:130::deaf] -sf uas-passive.sipp
+       sipp [2001:db8:130::deaf]:5060 -i [2001:db8:987::d00f] -sf uac.sipp -m 1
+
+It is even possible to run both client and server on the same host; there
+would also be two instances of ./user-display.sh running that each start
+one of the sides of the RTP session.
+
+This setup is really simple.  It does not register or authenticate, it won't
+handle exceptions, it will not tear down the connection, it will not even
+stop the RTT user session when SIP signals BYE.  Much more may be causing
+trouble.  This is not an end user application, but just a demo to help with
+RTT codec compliancy tests.
+
+
 Have fun!
 
 Rick van Rein
index f4ba330..904069f 100644 (file)
@@ -271,10 +271,18 @@ int main (int argc, char *argv []) {
        bzero (&remot, sizeof (remot));
        local.sin6_family = AF_INET6;
        remot.sin6_family = AF_INET6;
+       if ((*argv [1] == '[') && argv [1] [strlen (argv [1])-1] == ']') {
+               argv [1] [strlen (argv [1])-1] = 0;
+               argv [1]++;
+       }
        if (inet_pton (AF_INET6, argv [1], &local.sin6_addr) != 1) {
                fprintf (stderr, "Failed to parse local IPv6 address\n");
                exit (1);
        }
+       if ((*argv [3] == '[') && argv [3] [strlen (argv [3])-1] == ']') {
+               argv [3] [strlen (argv [3])-1] = 0;
+               argv [3]++;
+       }
        if (inet_pton (AF_INET6, argv [3], &remot.sin6_addr) != 1) {
                fprintf (stderr, "Failed to parse remote IPv6 address\n");
                exit (1);
index 8a01242..93e770d 100644 (file)
@@ -101,7 +101,9 @@ static void rtt_skipheader (uint8_t **msg, uint16_t *len, uint16_t *newseqptr, u
 
 void rtp_paytype_text_t140 (uint8_t *msg, uint16_t len) {
        uint16_t newseq;
-       //TODO:WAKEUP-TEXTSHOW-PROCESS// void rtt_recv_keys (uint8_t *text, uint16_t len);
+#ifdef TODO_WAKEUP_TEXTSHOW_PROCESS
+       void rtt_recv_keys (uint8_t *text, uint16_t len);
+#endif
        rtt_skipheader (&msg, &len, &newseq, NULL);
        switch ((int16_t) (newseq - rtt_seqnr)) {
        case -2:
@@ -111,11 +113,15 @@ void rtp_paytype_text_t140 (uint8_t *msg, uint16_t len) {
                return;
        default:
                /* Packets out of sync, report missing text */
-               //TODO:WAKEUP-TEXTSHOW-PROCESS// rtt_recv_keys (rtt_missing_text, sizeof (rtt_missing_text));
+#ifdef TODO_WAKEUP_TEXTSHOW_PROCESS
+               rtt_recv_keys (rtt_missing_text, sizeof (rtt_missing_text));
+#endif
                // ...continue into handling the one extension...
        case 1:
                /* Packets properly ordered */
-               //TODO:WAKEUP-TEXTSHOW-PROCESS// rtt_recv_keys (msg, len);
+#ifdef TODO_WAKEUP_TEXTSHOW_PROCESS
+               rtt_recv_keys (msg, len);
+#endif
                rtt_seqnr = newseq;
        }
 }
@@ -124,13 +130,17 @@ void rtp_paytype_text_t140 (uint8_t *msg, uint16_t len) {
 void rtp_paytype_text_red (uint8_t *msg, uint16_t len) {
        uint16_t newseq;
        uint16_t gencount, skipcount, skipbytes;
-       //TODO:WAKEUP-TEXTSHOW-PROCESS// void rtt_recv_keys (uint8_t *text, uint16_t len);
+#ifdef TODO_WAKEUP_TEXTSHOW_PROCESS
+       void rtt_recv_keys (uint8_t *text, uint16_t len);
+#endif
        rtt_skipheader (&msg, &len, &newseq, &gencount);
        //
        // Skip the redundant parts that were processed before
        if (gencount < (newseq - rtt_seqnr)) {
                /* Packets are missing -- report and use what is supplied */
-               //TODO:WAKEUP-TEXTSHOW-PROCESS// rtt_recv_keys (rtt_missing_text, sizeof (rtt_missing_text));
+#ifdef TODO_WAKEUP_TEXTSHOW_PROCESS
+               rtt_recv_keys (rtt_missing_text, sizeof (rtt_missing_text));
+#endif
                skipcount = 0;
        } else {
                /* No missing packets -- skip 0 or more redundant generations */
@@ -159,7 +169,9 @@ void rtp_paytype_text_red (uint8_t *msg, uint16_t len) {
        //
        // Copy the redundant parts that are new
        if (((int16_t) len) > 0) {
-               //TODO:WAKEUP-TEXTSHOW-PROCESS// rtt_recv_keys (msg, len);
+#ifdef TODO_WAKEUP_TEXTSHOW_PROCESS
+               rtt_recv_keys (msg, len);
+#endif
        }
 }
 
diff --git a/src/codec/rtt/uac.sipp b/src/codec/rtt/uac.sipp
new file mode 100644 (file)
index 0000000..c3571af
--- /dev/null
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+       uac.sipp
+
+       This is a scenario file for SIPP version 2.3.  Invocation:
+
+       sipp [::1]:5060 -i [::1] -sf uac.sipp -m 1
+
+       Replace [::1]:5060 with the remote peer's SIP address/port.
+       Replace [::1] with any IPv6 address to use for SIP and RTP.
+
+       It sits and waits for incoming Realtime Text SIP calls,
+       and starts the test utility from the local directory
+       when one comes in.  The call ends when the remote end
+       takes the initiative to do so.
+
+       This is hardly a functional phone, it is just an RTP
+       wrapper for test purposes.
+
+       This file is part of 0cpm Firmerware.
+       
+       0cpm Firmerware is Copyright (c)2011 Rick van Rein, OpenFortress.
+       
+       0cpm Firmerware is free software: you can redistribute it and/or
+       modify it under the terms of the GNU General Public License as
+       published by the Free Software Foundation, version 3.
+       
+       0cpm Firmerware is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+       
+       You should have received a copy of the GNU General Public License
+       along with 0cpm Firmerware.  If not, see <http://www.gnu.org/licenses/>.
+
+-->
+<scenario name="Passive RTT UAS">
+
+<send>
+<![CDATA[
+
+       INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+       Via: SIP/2.0/UDP [local_ip]:[local_port]
+       From: <sip:rtt@[local_ip]:[local_port]>;tag=[call_number]
+       To: <sip:[service]@[remote_ip]:[remote_port]>
+       Call-ID: [call_id]
+       CSeq: 1 INVITE
+       Contact: sip:sipp@[local_ip]:[local_port]
+       Server: SIPP testing RTT
+       Max-Forwards: 70
+       Content-Type: application/sdp
+       Content-Length: [len]
+
+       v=0
+       o=user1 53655765 2353687637 IN IP6 [local_ip]
+       s=-
+       c=IN IP6 [local_ip]
+       t=0 0
+       m=text 12000 RTP/AVP 98 100
+       a=rtpmap:98 t140/1000
+       a=rtpmap:100 red/1000
+       a=fmtp:100 98/98/98
+
+]]>
+</send>
+
+<recv response="100" optional="true"/>
+
+<recv response="183" optional="true"/>
+
+<recv response="200">
+  <action>
+       <ereg regexp="c=IN IP6 ([^\r\n]+)" search_in="body" check_it="true" assign_to="whole,remote_media_ip"/>
+       <ereg regexp="m=text ([0-9]+)" search_in="body" check_it="true" assign_to="whole,remote_media_port"/>
+       <log message="RTT remote_media=[$remote_media_ip]:[$remote_media_port]"/>
+       <exec command="echo > ./rtp-setup-pipe [local_ip] 12000 [$remote_media_ip] [$remote_media_port]"/>
+  </action>
+</recv>
+
+<send>
+<![CDATA[
+
+       ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+       Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+       From: <sip:rtt@[local_ip]:[local_port]>;tag=[call_number]
+       To: <sip:[service]@[remote_ip]:[remote_port]>;[peer_tag_param]
+       Call-ID: [call_id]
+       CSeq: 1 INVITE
+       Contact: sip:sipp@[local_ip]:[local_port]
+       Server: SIPP testing RTT
+       Max-Forwards: 70
+
+]]>
+</send>
+
+<recv request="BYE"/>
+
+<send>
+<![CDATA[
+
+       SIP/2.0 200 OK
+       Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+       From: <sip:rtt@[local_ip]:[local_port]>;tag=[call_number]
+       To: <sip:[service]@[remote_ip]:[remote_port]>;[peer_tag_param]
+       Call-ID: [call_id]
+       CSeq: [cseq] INVITE
+       Contact: <sip:[service]@[remote_ip]:[remote_port]>
+       Server: SIPP testing RTT
+       Max-Forwards: 70
+
+]]>
+</send>
+
+</scenario>
diff --git a/src/codec/rtt/uas-passive.sipp b/src/codec/rtt/uas-passive.sipp
new file mode 100644 (file)
index 0000000..84fe417
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+       uas-passive.sipp
+
+       This is a scenario file for SIPP version 2.3.  Invocation:
+
+       sipp -i [::1] -sf uas-passive.sipp
+
+       Replace ::1 with any IPv6 address to use for SIP and RTP.
+
+       It sits and waits for incoming Realtime Text SIP calls,
+       and starts the test utility from the local directory
+       when one comes in.  The call ends when the remote end
+       takes the initiative to do so.
+
+       This is hardly a functional phone, it is just an RTP
+       wrapper for test purposes.
+
+        This file is part of 0cpm Firmerware.
+  
+        0cpm Firmerware is Copyright (c)2011 Rick van Rein, OpenFortress.
+  
+        0cpm Firmerware is free software: you can redistribute it and/or
+        modify it under the terms of the GNU General Public License as
+        published by the Free Software Foundation, version 3.
+  
+        0cpm Firmerware is distributed in the hope that it will be useful,
+        but WITHOUT ANY WARRANTY; without even the implied warranty of
+        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+        GNU General Public License for more details.
+  
+        You should have received a copy of the GNU General Public License
+        along with 0cpm Firmerware.  If not, see <http://www.gnu.org/licenses/>.
+
+-->
+<scenario name="Passive RTT UAS">
+
+<recv request="INVITE">
+  <action>
+       <ereg regexp="c=IN IP6 ([^\r\n]+)" search_in="body" check_it="true" assign_to="whole,remote_media_ip"/>
+       <ereg regexp="m=text ([0-9]+)" search_in="body" check_it="true" assign_to="whole,remote_media_port"/>
+       <log message="RTT remote_media=[$remote_media_ip]:[$remote_media_port]"/>
+       <exec command="echo > ./rtp-setup-pipe [local_ip] 13000 [$remote_media_ip] [$remote_media_port]"/>
+  </action>
+</recv>
+
+<send>
+<![CDATA[
+
+       SIP/2.0 200 OK
+       Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+       From: <sip:[service]@[remote_ip]:[remote_port]>;[peer_tag_param]
+       To: <sip:rtt@[local_ip]:[local_port]>;tag=[call_number]
+       Call-ID: [call_id]
+       CSeq: [cseq] INVITE
+       Contact: <sip:TODO@[remote_ip]:[remote_port]>
+       Server: SIPP testing RTT
+       Max-Forwards: 70
+       Content-Type: application/sdp
+       Content-Length: [len]
+
+       v=0
+       o=user1 53655765 2353687637 IN IP6 [local_ip]
+       s=-
+       c=IN IP6 [local_ip]
+       t=0 0
+       m=text 13000 RTP/AVP 98 100
+       a=rtpmap:98 t140/1000
+       a=rtpmap:100 red/1000
+       a=fmtp:100 98/98/98
+
+]]>
+</send>
+
+<recv request="ACK"/>
+
+<recv request="BYE"/>
+
+<send>
+<![CDATA[
+
+       SIP/2.0 200 OK
+       Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+       From: <sip:[service]@[remote_ip]:[remote_port]>;[peer_tag_param]
+       To: <sip:rtt@[local_ip]:[local_port]>;tag=[call_number]
+       Call-ID: [call_id]
+       CSeq: [cseq] INVITE
+       Contact: <sip:TODO@[remote_ip]:[remote_port]>
+       Server: SIPP testing RTT
+       Max-Forwards: 70
+
+]]>
+</send>
+
+</scenario>
diff --git a/src/codec/rtt/user-display.sh b/src/codec/rtt/user-display.sh
new file mode 100755 (executable)
index 0000000..6c2add9
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# user-display.sh
+#
+# This is the chatty portion of the Realtime Text test environment.
+# It creates a pipe named "rtp-setuppipe" and waits until RTP hints
+# are received.  It the opens an RTT session for that data.
+#
+# This file is part of 0cpm Firmerware.
+#  
+# 0cpm Firmerware is Copyright (c)2011 Rick van Rein, OpenFortress.
+#  
+# 0cpm Firmerware is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, version 3.
+#  
+# 0cpm Firmerware is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#  
+# You should have received a copy of the GNU General Public License
+# along with 0cpm Firmerware.  If not, see <http://www.gnu.org/licenses/>.
+
+
+if [ ! -p ./rtp-setup-pipe ]
+then
+       echo >&2 'Creating ./rtp-setup-pipe'
+       rm -f ./rtp-setup-pipe
+       mknod ./rtp-setup-pipe p
+fi
+
+echo >&2 Waiting for RTP suggestion from SIPP scripts
+
+X=''
+while [ -z "$X" ]
+do
+       read < ./rtp-setup-pipe X
+done
+
+# X=`echo $X | sed 's/\[\([^ ]*\)\]/\1/g'`
+echo >&2 RTP local/remote coordinates: $X
+./rtt_desktop_test $X
+
index 81efde6..1c6be04 100644 (file)
@@ -353,7 +353,7 @@ void speex_finish_encode (struct codec *hdl) {
 void speex_transform_encode (struct codec *hdl,
                        uint16_t *pcm, uint16_t *pcmlen,
                        uint8_t  *pkt, uint16_t *pktlen) {
-       speex_encode (&hdl->state.state_speex_encode, NULL /*TODO*/);
+       speex_encode (&hdl->state.state_speex_encode, NULL /*TODO*/, NULL /*TODO*/);
 }
 void speex_init_decode (struct codec *hdl, uint32_t samplerate) {
        speex_decoder_init (&hdl->state.state_speex_decode);
@@ -362,7 +362,7 @@ void speex_finish_decode (struct codec *hdl) {
        speex_decoder_destroy (&hdl->state.state_speex_decode);
 }
 void speex_transform_decode (struct codec *hdl, uint16_t *pktlen) {
-       speex_decode (&hdl->state.state_speex_decode, NULL /*TODO*/);
+       speex_decode (&hdl->state.state_speex_decode, NULL /*TODO*/, NULL /*TODO*/);
 }
 
 #endif
@@ -415,6 +415,7 @@ struct codec_fun decoder_speex_ultra = {
 
 /********** CODEC2 DEFINITIONS **********/
 
+#ifdef CONFIG_CODEC_CODEC2
 static void codec2_init (struct codec *hdl, uint32_t samplerate) {
        //TODO// Static allocation
        codec2_create (&hdl->state.codec2_state);
@@ -440,8 +441,6 @@ static void codec2_transform_decode (struct codec *hdl,
        *pktlen = (CODEC2_BITS_PER_FRAME + 7) >> 3;
 }
 
-
-#ifdef CONFIG_CODEC_CODEC2
 struct codec_fun encoder_codec2_1500 = {
        "audio", "x-codec2", NULL,
        "CODEC2",
index 55814cd..6855b45 100644 (file)
@@ -177,7 +177,7 @@ bottom_led_set (LED_IDX_MESSAGE, 1);
 // bottom_led_set (LED_IDX_SPEAKERPHONE, 1);
        while (!(I2CSTR & REGVAL_I2CSTR_XRDY)) {
                if (I2CSTR & REGVAL_I2CSTR_NACK) {
-                       bottom_printf ("I2C received NACK\n");
+                       // bottom_printf ("I2C received NACK\n");
                        I2CSTR = REGVAL_I2CSTR_NACK;
                        I2CMDR = REGVAL_I2CMDR_MST | REGVAL_I2CMDR_STP | REGVAL_I2CMDR_NORESET | REGVAL_I2CMDR_FREE | REGVAL_I2CMDR_BC_8;
                        return;
@@ -280,7 +280,7 @@ static uint16_t samplebuf_wrapindex = BUFSZ;
  *     recordable      rec0    dma0
  *
  * DMA is possible if the dmaready area is non-empty, so if
- * dma0 != play0.  When DMA has finished transferring a block,
+ * dma0 != play0.  After DMA has transferred a block,
  * the dma0 pointer is incremented, and this is checked.
  *
  * bottom_record_claim() succeeds if rec0 != dma0, and when
@@ -289,17 +289,18 @@ static uint16_t samplebuf_wrapindex = BUFSZ;
  * it returns the rec0 offset of the playbuf, instead of the
  * rec0 offset in the recbuf as is returned by record_claim.
  *
- * bottom_play_claim() succeeds if play0 != rec0 *or* if there
- * is no actual recordable area, that is, rec0 == dma0.  This
+ * bottom_play_claim() succeeds if play0 != rec0 *or* if the
+ * buffer is empty, which is noticed if DMA is not active. This
  * means that playback is the first thing to start when a new
  * set of index pointers is setup with zero values.  When the
  * bottom_play_release() is called, play0 increments, and the
  * DMA conditions are evaluated.
  */
 
-static volatile uint16_t bufofs_play0 = 0;
-static volatile uint16_t bufofs_dma0  = 0;
-static volatile uint16_t bufofs_rec0  = 0;
+volatile bool dma_active = false;
+/*TODO:static*/ volatile uint16_t bufofs_play0 = 0;
+/*TODO:static*/ volatile uint16_t bufofs_dma0  = 0;
+/*TODO:static*/ volatile uint16_t bufofs_rec0  = 0;
 
 
 inline void bottom_bufferdma_progress (uint8_t chan) {
@@ -307,6 +308,7 @@ inline void bottom_bufferdma_progress (uint8_t chan) {
        bufofs_dma0 = (bufofs_dma0 + samplebuf_blocksize) % samplebuf_wrapindex;
        if (bufofs_dma0 == bufofs_play0) {
                SPCR2_1 &= ~REGVAL_SPCR2_FRST_NOTRESET;         // Stop DMA
+               dma_active = false;
        }
        if (recordinghint) {
                top_codec_can_record (chan);
@@ -314,7 +316,7 @@ inline void bottom_bufferdma_progress (uint8_t chan) {
 }
 
 int16_t *bottom_play_claim (uint8_t chan) {
-       if ((bufofs_play0 != bufofs_rec0) || (bufofs_rec0 == bufofs_dma0)) {
+       if ((!dma_active) || (bufofs_play0 != bufofs_rec0)) {
                return (int16_t *) &samplebuf_play [bufofs_play0];
        } else {
                return NULL;
@@ -332,6 +334,7 @@ void bottom_play_release (uint8_t chan) {
                DXR1_1 = DXR1_1;        // Flag down XEMPTY
                DMACCR_1 |= REGVAL_DMACCR_EN;
                SPCR2_1 |= REGVAL_SPCR2_FRST_NOTRESET;          // Start DMA
+               dma_active = true;
        }
 }
 
@@ -344,19 +347,19 @@ int16_t *bottom_record_claim (uint8_t chan) {
 }
 
 int16_t *bottom_echo_claim (uint8_t chan) {
-       bool playbackhint = (bufofs_rec0 == bufofs_play0);
        if (bufofs_rec0 != bufofs_dma0) {
                return (int16_t *) &samplebuf_play [bufofs_rec0];
        } else {
                return NULL;
        }
-       if (playbackhint) {
-               top_codec_can_play (chan);
-       }
 }
 
 void bottom_record_release (uint8_t chan) {
+       bool playbackhint = (bufofs_rec0 == bufofs_play0);
        bufofs_rec0 = (bufofs_rec0 + samplebuf_blocksize) % samplebuf_wrapindex;
+       if (playbackhint) {
+               top_codec_can_play (chan);
+       }
 }
 
 static int TODO_setratectr = 0;
@@ -365,13 +368,11 @@ static int TODO_setratectr = 0;
 //TODO// Not all this code is properly split between generic TLV and specific BT200
 void tlv320aic2x_set_samplerate (uint8_t chan, uint32_t samplerate) {
        uint16_t m, n, p;
-#if 0
        SPCR2_1 |= REGVAL_SPCR2_GRST_NOTRESET | REGVAL_SPCR2_FRST_NOTRESET;
 { uint32_t ctr = 100; while (ctr-- > 0) ; }
        SPCR1_1 |= REGVAL_SPCR1_RRST_NOTRESET;
        SPCR2_1 |= REGVAL_SPCR2_XRST_NOTRESET;
 { uint32_t ctr = 10000; while (ctr-- > 0) ; }
-#endif
        DXR1_1 = DXR1_1;        // Flag down XEMPTY
 tlv320aic2x_setreg (chan, 3, 0x31);    // Channel offline
 { uint32_t ctr = 1000; while (ctr-- > 0) ; }
@@ -381,7 +382,7 @@ tlv320aic2x_setreg (chan, 3, 0x31); // Channel offline
        n = 1;
        p = 2;
        m = ( 30720000 / 16 ) / ( n * p * samplerate );
-       if (m & 0x03 == 0x00) {
+       if ((m & 0x03) == 0x00) {
                // Save PLL energy without compromising accuracy
                p = 8;          // Factor 2 -> 8 so multiplied by 4
                m >>= 2;        // Divide by 4
@@ -391,7 +392,9 @@ tlv320aic2x_setreg (chan, 3, 0x31); // Channel offline
                n <<= 1;
        }
 { uint8_t ip4 [4]; ip4 [0] = m; ip4 [1] = n; ip4 [2] = p; ip4 [3] = ++TODO_setratectr; bottom_show_ip4 (APP_LEVEL_CONNECTING, ip4); }
+#ifdef CONFIG_FUNCTION_NETCONSOLE
 bottom_printf ("TLV320AIC20K setting: M=%d, N=%d, P=%d\n", (intptr_t) m, (intptr_t) n, (intptr_t) p);
+#endif
        m &= 0x7f;
        n &= 0x0f;      // Ignore range problems?
        p &= 0x07;
@@ -449,6 +452,7 @@ void bottom_soundchannel_set_samplerate (uint8_t chan, uint32_t samplerate,
        tlv320aic2x_set_samplerate (chan, samplerate);
        //
        // Setup buffer index pointers at the start; effectively clearing all
+       dma_active = false;
        bufofs_play0 = 0;
        bufofs_dma0  = 0;
        bufofs_rec0  = 0;
@@ -534,7 +538,9 @@ void dmahint_play (void) {
        if ((available_play >= 64) && ! (DMACCR_1 & REGVAL_DMACCR_EN)) {
                DXR1_1 = DXR1_1;        // Flag down XEMPTY
                DMACCR_1 |= REGVAL_DMACCR_EN;
+#ifdef CONFIG_FUNCTION_NETCONSOLE
 bottom_printf ("dmahint_play() started playing DMA\n");
+#endif
 // #ifdef TODO_FS_ONLY_DURING_SOUND_IO
                // SPCR2_1 |= REGVAL_SPCR2_XRST_NOTRESET | REGVAL_SPCR2_GRST_NOTRESET | REGVAL_SPCR2_FRST_NOTRESET;
 // #endif
@@ -1171,7 +1177,7 @@ EGCR2 = 0x0005;   //ECLKOUT2-DIV-2//
        tic55x_setup_timers ();
        tic55x_setup_interrupts ();
        ht162x_setup_lcd ();
-       // tlv320aic2x_set_samplerate (0, 8000);
+       tlv320aic2x_set_samplerate (0, 8000);
        tlv320aic2x_setup_sound ();
        ksz8842_setup_network ();
        // Enable INT0..INT3
index 5b1ad9f..83de75e 100644 (file)
@@ -15,11 +15,14 @@ SECTIONS {
        // .text                        > ROM
        .text                   > RAM
        .text_quick             > DARAM
-       .switch                 > ROM
-       .const                  > ROM
+       // .switch                      > ROM
+       .switch                 > CONSTRAM
+       // .const                       > ROM
+       .const                  > CONSTRAM
        // .const                       > CONSTRAM
        .const_codec2_codebook  > CONSTRAM
-       .cinit                  > ROM
+       // .cinit                       > ROM
+       .cinit                  > CONSTRAM
        .interrupts             > VECTOR
        .isrmap                 > ISRMAP
        .data                   > RAM
index 148bbcd..7206319 100644 (file)
@@ -1,6 +1,6 @@
 # Function for the target image
 
-menu "5. Firmerware functions"
+menu "4. Firmerware functions"
 
 choice
        prompt "Primary firmware function"
@@ -98,7 +98,7 @@ config FUNCTION_SOUND_PLAYER
 
 config FUNCTION_RADIO
        bool "Internet radio (multicast reception)"
-       depends on UNIMPLEMENTED
+       depends on UNIMPLEMENTED && !MAINFUNCTION_DEVEL_GPIO && !MAINFUNCTION_DEVEL_TIMER && !MAINFUNCTION_DEVEL_KEYBOARD && !MAINFUNCTION_DEVEL_NETWORK && !MAINFUNCTION_DEVEL_SOUND
        default y
        help
          Enable Internet Radio functions.  This makes the phone pickup
@@ -186,6 +186,4 @@ config FUNCTION_FIRMWARE_UPGRADES_BOOTLOADER
 
          TODO: a polling TFTP client may in fact be better?
 
-source "src/codec/Kconfig"
-
 endmenu
index 3f177fa..833b5f1 100644 (file)
@@ -62,12 +62,14 @@ void top_hook_update (bool offhook) {
        }
 }
 
+bool online;
+
 void top_network_online (void) {
-        /* Keep the linker happy */ ;
+        online = true;
 }
 
 void top_network_offline (void) {
-        /* Keep the linker happy */ ;
+        online = false;
 }
 
 void top_network_can_send (void) {
@@ -154,14 +156,13 @@ int8_t sinewaveL16 [128] = {
 
 void top_main_sine_1khz (void) {
        uint16_t oldirqs = 0;
-extern volatile uint16_t available_play;
-extern volatile uint16_t available_record;
-uint8_t l16ctr = 1;
        bottom_critical_region_end ();
        if (!bottom_soundchannel_acceptable_samplerate (PHONE_CHANNEL_TELEPHONY, 8000)) {
                bottom_printf ("Failed to set sample rate");
                bottom_show_fixed_msg (APP_LEVEL_ZERO, FIXMSG_CALL_ENDED);
-               exit (1);
+               while (1) {
+                       ;
+               }
        }
        bottom_soundchannel_set_samplerate (PHONE_CHANNEL_TELEPHONY, 8000, 64, 1, 1);
        bottom_soundchannel_setvolume (PHONE_CHANNEL_TELEPHONY, 127);
@@ -169,16 +170,10 @@ uint8_t l16ctr = 1;
        bottom_printf ("Playing 1 kHz tone to speaker or handset\n");
        top_hook_update (bottom_phone_is_offhook ());
        while (true) {
-#if 0
-if (SPCR2_1 & REGVAL_SPCR2_XRDY) { DXR1_1 = sinewaveL16 [l16ctr++]; if (l16ctr == 8) { l16ctr = 0; } }
-{ uint16_t _ = DRR1_1; }
-#else
-               do {
-                       int16_t *outbuf = bottom_play_claim (PHONE_CHANNEL_TELEPHONY);
+               /* First play as many samples as possible */
+               int16_t *outbuf;
+               while ((outbuf = bottom_play_claim (PHONE_CHANNEL_TELEPHONY))) {
                        uint16_t pcmlen, pktlen;
-                       if (!outbuf) {
-                               break;
-                       }
 #if 1
                        pcmlen = 64;
                        pktlen = 64;
@@ -191,22 +186,26 @@ if (SPCR2_1 & REGVAL_SPCR2_XRDY) { DXR1_1 = sinewaveL16 [l16ctr++]; if (l16ctr =
                        l16_decode (NULL, outbuf, &pcmlen, sinewaveL16, &pktlen);
 #endif
                        bottom_play_release (PHONE_CHANNEL_TELEPHONY);
-               } while (true);
-#endif
+               }
+               /* Now let the bottom think that recordings have been processed */
+               while (bottom_record_claim (PHONE_CHANNEL_TELEPHONY)) {
+                       bottom_record_release (PHONE_CHANNEL_TELEPHONY);
+               }
+{extern volatile uint16_t bufofs_play0, bufofs_dma0, bufofs_rec0;
+bottom_printf ("p/d/r = %d, %d, %d\n", (intptr_t) bufofs_play0, (intptr_t) bufofs_dma0, (intptr_t) bufofs_rec0);
+}
 
 #ifdef CONFIG_FUNCTION_NETCONSOLE
-               // { uint32_t ctr = 10000; while (ctr--) ; }
-               trysend ();
-               // { uint32_t ctr = 10000; while (ctr--) ; }
 bottom_led_set (LED_IDX_BACKLIGHT, 1);
-               netinputlen = sizeof (netinput);
-               if (bottom_network_recv (netinput, &netinputlen)) {
-                       nethandler_llconly (netinput, netinputlen);
-bottom_led_set (LED_IDX_BACKLIGHT, 0);
-                       { uint32_t ctr = 10000; while (ctr--) ; }
+               if (online) {
+                       netinputlen = sizeof (netinput);
+                       if (bottom_network_recv (netinput, &netinputlen)) {
+                               nethandler_llconly (netinput, netinputlen);
+                               { uint32_t ctr = 10000; while (ctr--) ; }
+                       }
+                       trysend ();
                }
 bottom_led_set (LED_IDX_BACKLIGHT, 0);
-               trysend ();
 #endif
 
 #if defined NEED_KBD_SCANNER_BETWEEN_KEYS || defined NEED_KBD_SCANNER_DURING_KEYPRESS
@@ -272,6 +271,7 @@ memset (samples, 0x33, sizeof (samples));
                pktlen = 100;
                // Note: No handle needed for stateless L8
                l8_decode (NULL, buf, &pcmlen, samples + recptr, &pktlen);
+               bottom_record_release (PHONE_CHANNEL_TELEPHONY);
 
                recptr += 100;
                if (recptr >= 10000) {
index b7ae336..9595ce0 100644 (file)
@@ -28,5 +28,8 @@ source "src/target/Kconfig.platform"
 # 4. Intended functionality
 source "src/function/Kconfig"
 
+# 5. Codec support
+source "src/codec/Kconfig"
+
 source "src/net/Kconfig"
 source "src/phone/Kconfig"
index 2ee9ffa..8743a09 100644 (file)
@@ -70,6 +70,9 @@ config TARGET_GRANDSTREAM_GXP_OTHER
          this software.  And of course we will gladly integrate your
          changes, so you don't have to keep your own code forked.
 
+         For the latest news on the support for these phones, visit
+         http://reverse.0cpm.org/grandstream/gxp.html
+
 config TARGET_GRANDSTREAM_GXV
        bool "Grandstream GXV series (video phones)"
        select PLATFORM_TIC55X
@@ -83,7 +86,8 @@ config TARGET_GRANDSTREAM_GXV
           * camera
           * touch screen (on some models)
 
-         Support for these models is not planned at this time.
+         For the latest news on the support for these phones, visit
+         http://reverse.0cpm.org/grandstream/gxv.html
 
 endchoice