* #36737: switch back to svn repo, remove assert in sip_transaction.c
diff --git a/jni/pjproject-android/.svn/pristine/f7/f71507511d7cc5630ce19de5937259918703e557.svn-base b/jni/pjproject-android/.svn/pristine/f7/f71507511d7cc5630ce19de5937259918703e557.svn-base
new file mode 100644
index 0000000..70a3b5f
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f7/f71507511d7cc5630ce19de5937259918703e557.svn-base
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<!-- This program 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; either version 2 of the -->
+<!-- License, or (at your option) any later version. -->
+<!-- -->
+<!-- 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 General Public License for more details. -->
+<!-- -->
+<!-- You should have received a copy of the GNU General Public License -->
+<!-- along with this program; if not, write to the -->
+<!-- Free Software Foundation, Inc., -->
+<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
+<!-- -->
+<!-- Sipp default 'uas' scenario. -->
+<!-- -->
+
+<scenario name="UAS answer 200/INVITE without SDP (#1045)">
+ <!-- By adding rrs="true" (Record Route Sets), the route sets -->
+ <!-- are saved and used for following messages sent. Useful to test -->
+ <!-- against stateful SIP proxies/B2BUAs. -->
+
+ <recv request="INVITE" crlf="true">
+ </recv>
+
+ <send retrans="500">
+ <![CDATA[
+
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Content-Type: application/sdp
+ Content-Length: [len]
+
+ ]]>
+ </send>
+
+ <recv request="ACK" crlf="true">
+ </recv>
+
+
+ <recv request="BYE" crlf="true">
+ </recv>
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Content-Length: [len]
+
+ ]]>
+ </send>
+
+ <!-- Keep the call open for a while in case the 200 is lost to be -->
+ <!-- able to retransmit it if we receive the BYE again. -->
+ <pause milliseconds="4000"/>
+
+
+ <!-- definition of the response time repartition table (unit is ms) -->
+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+ <!-- definition of the call length repartition table (unit is ms) -->
+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
diff --git a/jni/pjproject-android/.svn/pristine/f7/f75f76d22188b3c6656f86afae0f658db6f60a29.svn-base b/jni/pjproject-android/.svn/pristine/f7/f75f76d22188b3c6656f86afae0f658db6f60a29.svn-base
new file mode 100644
index 0000000..bc647ce
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f7/f75f76d22188b3c6656f86afae0f658db6f60a29.svn-base
@@ -0,0 +1,20 @@
+include build.mak
+include build/host-$(HOST_NAME).mak
+
+DIRS = pjlib pjlib-util pjnath pjmedia pjsip
+
+ifdef MINSIZE
+MAKE_FLAGS := MINSIZE=1
+endif
+
+export CPP_MODE=1
+
+all clean dep depend distclean doc print realclean:
+ for dir in $(DIRS); do \
+ if $(MAKE) $(MAKE_FLAGS) -C $$dir/build $@; then \
+ true; \
+ else \
+ exit 1; \
+ fi; \
+ done
+
diff --git a/jni/pjproject-android/.svn/pristine/f7/f76fcb262e39e254d7fc353645b4b933049f040d.svn-base b/jni/pjproject-android/.svn/pristine/f7/f76fcb262e39e254d7fc353645b4b933049f040d.svn-base
new file mode 100644
index 0000000..fff2089
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f7/f76fcb262e39e254d7fc353645b4b933049f040d.svn-base
@@ -0,0 +1,166 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJLIB_UTIL_CLI_TELNET_H__
+#define __PJLIB_UTIL_CLI_TELNET_H__
+
+/**
+ * @file cli_telnet.h
+ * @brief Command Line Interface Telnet Front End API
+ */
+
+#include <pjlib-util/cli_imp.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @ingroup PJLIB_UTIL_CLI_IMP
+ * @{
+ *
+ */
+
+ /**
+ * This structure contains the information about the telnet.
+ * Application will get updated information each time the telnet is started/
+ * restarted.
+ */
+typedef struct pj_cli_telnet_info
+{
+ /**
+ * The telnet's ip address.
+ */
+ pj_str_t ip_address;
+
+ /**
+ * The telnet's port number.
+ */
+ pj_uint16_t port;
+
+ /* Internal buffer for IP address */
+ char buf_[32];
+
+} pj_cli_telnet_info;
+
+/**
+ * This specifies the callback called when telnet is started
+ *
+ * @param status The status of telnet startup process.
+ *
+ */
+typedef void (*pj_cli_telnet_on_started)(pj_status_t status);
+
+/**
+ * This structure contains various options to instantiate the telnet daemon.
+ * Application must call pj_cli_telnet_cfg_default() to initialize
+ * this structure with its default values.
+ */
+typedef struct pj_cli_telnet_cfg
+{
+ /**
+ * Listening port number. The value may be 0 to let the system choose
+ * the first available port.
+ *
+ * Default value: PJ_CLI_TELNET_PORT
+ */
+ pj_uint16_t port;
+
+ /**
+ * Ioqueue instance to be used. If this field is NULL, an internal
+ * ioqueue and worker thread will be created.
+ */
+ pj_ioqueue_t *ioqueue;
+
+ /**
+ * Default log verbosity level for the session.
+ *
+ * Default value: PJ_CLI_TELNET_LOG_LEVEL
+ */
+ int log_level;
+
+ /**
+ * Specify a password to be asked to the end user to access the
+ * application.
+ *
+ * Default: empty (no password)
+ */
+ pj_str_t passwd;
+
+ /**
+ * Specify text message to be displayed to newly connected users.
+ *
+ * Default: empty
+ */
+ pj_str_t welcome_msg;
+
+ /**
+ * Specify text message as a prompt string to user.
+ *
+ * Default: empty
+ */
+ pj_str_t prompt_str;
+
+ /**
+ * Specify the pj_cli_telnet_on_started callback.
+ *
+ * Default: empty
+ */
+ pj_cli_telnet_on_started on_started;
+
+} pj_cli_telnet_cfg;
+
+/**
+ * Initialize pj_cli_telnet_cfg with its default values.
+ *
+ * @param param The structure to be initialized.
+ */
+PJ_DECL(void) pj_cli_telnet_cfg_default(pj_cli_telnet_cfg *param);
+
+
+/**
+ * Create, initialize, and start a telnet daemon for the application.
+ *
+ * @param cli The CLI application instance.
+ * @param param Optional parameters for creating the telnet daemon.
+ * If this value is NULL, default parameters will be used.
+ * @param p_fe Optional pointer to receive the front-end instance
+ * of the telnet front-end just created.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_cli_telnet_create(pj_cli_t *cli,
+ pj_cli_telnet_cfg *param,
+ pj_cli_front_end **p_fe);
+
+
+/**
+ * Retrieve cli telnet info.
+ *
+ * @param telnet_info The telnet runtime information.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_cli_telnet_get_info(pj_cli_front_end *fe,
+ pj_cli_telnet_info *info);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJLIB_UTIL_CLI_TELNET_H__ */
diff --git a/jni/pjproject-android/.svn/pristine/f7/f770a2caa97b0b08d37fef32d8252de4fdcee4b7.svn-base b/jni/pjproject-android/.svn/pristine/f7/f770a2caa97b0b08d37fef32d8252de4fdcee4b7.svn-base
new file mode 100644
index 0000000..049f77d
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f7/f770a2caa97b0b08d37fef32d8252de4fdcee4b7.svn-base
@@ -0,0 +1,373 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/wsola.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+#include <pj/os.h>
+#include <stdio.h>
+#include <assert.h>
+
+#define CLOCK_RATE 16000
+#define SAMPLES_PER_FRAME (10 * CLOCK_RATE / 1000)
+
+#define RESET() memset(buf1, 0, sizeof(buf1)), \
+ memset(buf2, 0, sizeof(buf2)), \
+ memset(frm1, 0, sizeof(frm1)), \
+ memset(frm2, 0, sizeof(frm2))
+
+#if 0
+void test_find_pitch(void)
+{
+ enum { ON = 111, FRM_PART_LEN=20 };
+ short buf2[SAMPLES_PER_FRAME*2], buf1[SAMPLES_PER_FRAME*2],
+ frm2[SAMPLES_PER_FRAME], frm1[SAMPLES_PER_FRAME];
+ short *ref, *pos;
+
+ /* Case 1. all contiguous */
+ RESET();
+ ref = buf1 + 10;
+ *ref = ON;
+ frm1[0] = ON;
+
+ pos = pjmedia_wsola_find_pitch(frm1, SAMPLES_PER_FRAME, NULL, 0,
+ buf1, SAMPLES_PER_FRAME*2, NULL, 0, PJ_TRUE);
+ assert(pos == ref);
+
+ /* Case 2: contiguous buffer, non-contiguous frame */
+ RESET();
+ ref = buf1 + 17;
+ *ref = ON;
+ *(ref+FRM_PART_LEN) = ON;
+ frm1[0] = ON;
+ frm2[0] = ON;
+
+ /* Noise */
+ buf1[0] = ON;
+
+ pos = pjmedia_wsola_find_pitch(frm1, FRM_PART_LEN, frm2, SAMPLES_PER_FRAME - FRM_PART_LEN,
+ buf1, SAMPLES_PER_FRAME*2, NULL, 0, PJ_TRUE);
+ assert(pos == ref);
+
+ /* Case 3: non-contiguous buffer, contiguous frame, found in buf1 */
+ RESET();
+ ref = buf1 + 17;
+ *ref = ON;
+ buf2[17] = ON;
+ frm1[0] = ON;
+ frm1[FRM_PART_LEN] = ON;
+
+ /* Noise */
+ buf1[0] = ON;
+
+ pos = pjmedia_wsola_find_pitch(frm1, SAMPLES_PER_FRAME, NULL, 0,
+ buf1, FRM_PART_LEN,
+ buf2, SAMPLES_PER_FRAME,
+ PJ_TRUE);
+
+ assert(pos == ref);
+}
+#endif
+
+int expand(pj_pool_t *pool, const char *filein, const char *fileout,
+ int expansion_rate100, int lost_rate10, int lost_burst)
+{
+ enum { LOST_RATE = 10 };
+ FILE *in, *out;
+ short frame[SAMPLES_PER_FRAME];
+ pjmedia_wsola *wsola;
+ pj_timestamp elapsed, zero;
+ unsigned samples;
+ int last_lost = 0;
+
+ /* Lost burst must be > 0 */
+ assert(lost_rate10==0 || lost_burst > 0);
+
+ in = fopen(filein, "rb");
+ if (!in) return 1;
+ out = fopen(fileout, "wb");
+ if (!out) return 1;
+
+ pjmedia_wsola_create(pool, CLOCK_RATE, SAMPLES_PER_FRAME, 1, 0, &wsola);
+
+ samples = 0;
+ elapsed.u64 = 0;
+
+ while (fread(frame, SAMPLES_PER_FRAME*2, 1, in) == 1) {
+ pj_timestamp t1, t2;
+
+ if (lost_rate10 == 0) {
+
+ /* Expansion */
+ pj_get_timestamp(&t1);
+ pjmedia_wsola_save(wsola, frame, 0);
+ pj_get_timestamp(&t2);
+
+ pj_sub_timestamp(&t2, &t1);
+ pj_add_timestamp(&elapsed, &t2);
+
+ fwrite(frame, SAMPLES_PER_FRAME*2, 1, out);
+
+ samples += SAMPLES_PER_FRAME;
+
+ if ((rand() % 100) < expansion_rate100) {
+
+ pj_get_timestamp(&t1);
+ pjmedia_wsola_generate(wsola, frame);
+ pj_get_timestamp(&t2);
+
+ pj_sub_timestamp(&t2, &t1);
+ pj_add_timestamp(&elapsed, &t2);
+
+ samples += SAMPLES_PER_FRAME;
+
+ fwrite(frame, SAMPLES_PER_FRAME*2, 1, out);
+ }
+
+ } else {
+ /* Lost */
+
+ if ((rand() % 10) < lost_rate10) {
+ int burst;
+
+ for (burst=0; burst<lost_burst; ++burst) {
+ pj_get_timestamp(&t1);
+ pjmedia_wsola_generate(wsola, frame);
+ pj_get_timestamp(&t2);
+
+ pj_sub_timestamp(&t2, &t1);
+ pj_add_timestamp(&elapsed, &t2);
+
+ samples += SAMPLES_PER_FRAME;
+
+ fwrite(frame, SAMPLES_PER_FRAME*2, 1, out);
+ }
+ last_lost = 1;
+ } else {
+ pj_get_timestamp(&t1);
+ pjmedia_wsola_save(wsola, frame, last_lost);
+ pj_get_timestamp(&t2);
+
+ pj_sub_timestamp(&t2, &t1);
+ pj_add_timestamp(&elapsed, &t2);
+
+ samples += SAMPLES_PER_FRAME;
+
+ fwrite(frame, SAMPLES_PER_FRAME*2, 1, out);
+ last_lost = 0;
+ }
+
+ }
+
+ }
+
+ zero.u64 = 0;
+ zero.u64 = pj_elapsed_usec(&zero, &elapsed);
+
+ zero.u64 = samples * PJ_INT64(1000000) / zero.u64;
+ assert(zero.u32.hi == 0);
+
+ PJ_LOG(3,("test.c", "Processing: %f Msamples per second",
+ zero.u32.lo/1000000.0));
+ PJ_LOG(3,("test.c", "CPU load for current settings: %f%%",
+ CLOCK_RATE * 100.0 / zero.u32.lo));
+
+ pjmedia_wsola_destroy(wsola);
+ fclose(in);
+ fclose(out);
+
+ return 0;
+}
+
+static void save_file(const char *file,
+ short frame[], unsigned count)
+{
+ FILE *f = fopen(file, "wb");
+ fwrite(frame, count, 2, f);
+ fclose(f);
+}
+
+int compress(pj_pool_t *pool,
+ const char *filein, const char *fileout,
+ int rate10)
+{
+ enum { BUF_CNT = SAMPLES_PER_FRAME * 10 };
+ FILE *in, *out;
+ pjmedia_wsola *wsola;
+ short buf[BUF_CNT];
+ pj_timestamp elapsed, zero;
+ unsigned samples = 0;
+
+ in = fopen(filein, "rb");
+ if (!in) return 1;
+ out = fopen(fileout, "wb");
+ if (!out) return 1;
+
+ pjmedia_wsola_create(pool, CLOCK_RATE, SAMPLES_PER_FRAME, 1, 0, &wsola);
+
+ elapsed.u64 = 0;
+
+ for (;;) {
+ unsigned size_del, count;
+ pj_timestamp t1, t2;
+ int i;
+
+ if (fread(buf, sizeof(buf), 1, in) != 1)
+ break;
+
+ count = BUF_CNT;
+ size_del = 0;
+ pj_get_timestamp(&t1);
+
+ for (i=0; i<rate10; ++i) {
+ unsigned to_del = SAMPLES_PER_FRAME;
+#if 0
+ /* Method 1: buf1 contiguous */
+ pjmedia_wsola_discard(wsola, buf, count, NULL, 0, &to_del);
+#elif 0
+ /* Method 2: split, majority in buf1 */
+ assert(count > SAMPLES_PER_FRAME);
+ pjmedia_wsola_discard(wsola, buf, count-SAMPLES_PER_FRAME,
+ buf+count-SAMPLES_PER_FRAME, SAMPLES_PER_FRAME,
+ &to_del);
+#elif 0
+ /* Method 3: split, majority in buf2 */
+ assert(count > SAMPLES_PER_FRAME);
+ pjmedia_wsola_discard(wsola, buf, SAMPLES_PER_FRAME,
+ buf+SAMPLES_PER_FRAME, count-SAMPLES_PER_FRAME,
+ &to_del);
+#elif 1
+ /* Method 4: split, each with small length */
+ enum { TOT_LEN = 3 * SAMPLES_PER_FRAME };
+ unsigned buf1_len = (rand() % TOT_LEN);
+ short *ptr = buf + count - TOT_LEN;
+ assert(count > TOT_LEN);
+ if (buf1_len==0) buf1_len=SAMPLES_PER_FRAME*2;
+ pjmedia_wsola_discard(wsola, ptr, buf1_len,
+ ptr+buf1_len, TOT_LEN-buf1_len,
+ &to_del);
+#endif
+ count -= to_del;
+ size_del += to_del;
+ }
+ pj_get_timestamp(&t2);
+
+ samples += BUF_CNT;
+
+ pj_sub_timestamp(&t2, &t1);
+ pj_add_timestamp(&elapsed, &t2);
+
+ assert(size_del >= SAMPLES_PER_FRAME);
+
+ fwrite(buf, count, 2, out);
+ }
+
+ pjmedia_wsola_destroy(wsola);
+ fclose(in);
+ fclose(out);
+
+ zero.u64 = 0;
+ zero.u64 = pj_elapsed_usec(&zero, &elapsed);
+
+ zero.u64 = samples * PJ_INT64(1000000) / zero.u64;
+ assert(zero.u32.hi == 0);
+
+ PJ_LOG(3,("test.c", "Processing: %f Msamples per second",
+ zero.u32.lo/1000000.0));
+ PJ_LOG(3,("test.c", "CPU load for current settings: %f%%",
+ CLOCK_RATE * 100.0 / zero.u32.lo));
+
+ return 0;
+}
+
+
+static void mem_test(pj_pool_t *pool)
+{
+ char unused[1024];
+ short *frame = pj_pool_alloc(pool, 240+4*160);
+ pj_timestamp elapsed, zero, t1, t2;
+ unsigned samples = 0;
+
+ elapsed.u64 = 0;
+ while (samples < 50000000) {
+
+ pj_get_timestamp(&t1);
+ pjmedia_move_samples(frame, frame+160, 240+2*160);
+ pj_get_timestamp(&t2);
+ pj_sub_timestamp(&t2, &t1);
+
+ elapsed.u64 += t2.u64;
+
+ memset(unused, 0, sizeof(unused));
+ samples += 160;
+ }
+
+
+
+
+ zero.u64 = 0;
+ zero.u64 = pj_elapsed_usec(&zero, &elapsed);
+
+ zero.u64 = samples * PJ_INT64(1000000) / zero.u64;
+ assert(zero.u32.hi == 0);
+
+ PJ_LOG(3,("test.c", "Processing: %f Msamples per second",
+ zero.u32.lo/1000000.0));
+ PJ_LOG(3,("test.c", "CPU load for current settings: %f%%",
+ CLOCK_RATE * 100.0 / zero.u32.lo));
+
+}
+
+int main()
+{
+ pj_caching_pool cp;
+ pj_pool_t *pool;
+ int i, rc;
+
+ //test_find_pitch();
+
+ pj_init();
+ pj_caching_pool_init(&cp, NULL, 0);
+ pool = pj_pool_create(&cp.factory, "", 1000, 1000, NULL);
+
+ srand(2);
+
+ rc = expand(pool, "galileo16.pcm", "temp1.pcm", 20, 0, 0);
+ rc = compress(pool, "temp1.pcm", "output.pcm", 1);
+
+ for (i=0; i<2; ++i) {
+ rc = expand(pool, "output.pcm", "temp1.pcm", 20, 0, 0);
+ rc = compress(pool, "temp1.pcm", "output.pcm", 1);
+ }
+
+ if (rc != 0) {
+ puts("Error");
+ return 1;
+ }
+
+#if 0
+ {
+ char s[10];
+ puts("Press ENTER to quit");
+ fgets(s, sizeof(s), stdin);
+ }
+#endif
+
+ return 0;
+}
diff --git a/jni/pjproject-android/.svn/pristine/f7/f7876ed825b0444ba52d528f9107b068d11c5faf.svn-base b/jni/pjproject-android/.svn/pristine/f7/f7876ed825b0444ba52d528f9107b068d11c5faf.svn-base
new file mode 100644
index 0000000..06de5be
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f7/f7876ed825b0444ba52d528f9107b068d11c5faf.svn-base
@@ -0,0 +1,55 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJ_COMPAT_CC_GCCE_H__
+#define __PJ_COMPAT_CC_GCCE_H__
+
+/**
+ * @file cc_gcce.h
+ * @brief Describes GCCE compiler specifics.
+ */
+
+#ifndef __GCCE__
+# error "This file is only for gcce!"
+#endif
+
+#define PJ_CC_NAME "gcce"
+#define PJ_CC_VER_1 __GCCE__
+#define PJ_CC_VER_2 __GCCE_MINOR__
+#define PJ_CC_VER_3 __GCCE_PATCHLEVEL__
+
+
+#define PJ_INLINE_SPECIFIER static inline
+#define PJ_THREAD_FUNC
+#define PJ_NORETURN
+#define PJ_ATTR_NORETURN __attribute__ ((noreturn))
+#define PJ_ATTR_MAY_ALIAS __attribute__ ((__may_alias__))
+
+#define PJ_HAS_INT64 1
+
+typedef long long pj_int64_t;
+typedef unsigned long long pj_uint64_t;
+
+#define PJ_INT64(val) val##LL
+#define PJ_UINT64(val) val##LLU
+#define PJ_INT64_FMT "L"
+
+
+#endif /* __PJ_COMPAT_CC_GCCE_H__ */
+
diff --git a/jni/pjproject-android/.svn/pristine/f7/f7893352e199a79bc9920d4ccf77d53f699bcbe2.svn-base b/jni/pjproject-android/.svn/pristine/f7/f7893352e199a79bc9920d4ccf77d53f699bcbe2.svn-base
new file mode 100644
index 0000000..c161f98
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f7/f7893352e199a79bc9920d4ccf77d53f699bcbe2.svn-base
@@ -0,0 +1,72 @@
+
+ /******************************************************************
+
+ iLBC Speech Coder ANSI-C Source Code
+
+ anaFilter.c
+
+ Copyright (C) The Internet Society (2004).
+ All Rights Reserved.
+
+ ******************************************************************/
+
+ #include <string.h>
+ #include "iLBC_define.h"
+
+ /*----------------------------------------------------------------*
+ * LP analysis filter.
+ *---------------------------------------------------------------*/
+
+ void anaFilter(
+ float *In, /* (i) Signal to be filtered */
+ float *a, /* (i) LP parameters */
+ int len,/* (i) Length of signal */
+ float *Out, /* (o) Filtered signal */
+ float *mem /* (i/o) Filter state */
+ ){
+ int i, j;
+ float *po, *pi, *pm, *pa;
+
+ po = Out;
+
+ /* Filter first part using memory from past */
+
+ for (i=0; i<LPC_FILTERORDER; i++) {
+ pi = &In[i];
+ pm = &mem[LPC_FILTERORDER-1];
+ pa = a;
+ *po=0.0;
+
+
+
+
+
+ for (j=0; j<=i; j++) {
+ *po+=(*pa++)*(*pi--);
+ }
+ for (j=i+1; j<LPC_FILTERORDER+1; j++) {
+
+ *po+=(*pa++)*(*pm--);
+ }
+ po++;
+ }
+
+ /* Filter last part where the state is entirely
+ in the input vector */
+
+ for (i=LPC_FILTERORDER; i<len; i++) {
+ pi = &In[i];
+ pa = a;
+ *po=0.0;
+ for (j=0; j<LPC_FILTERORDER+1; j++) {
+ *po+=(*pa++)*(*pi--);
+ }
+ po++;
+ }
+
+ /* Update state vector */
+
+ memcpy(mem, &In[len-LPC_FILTERORDER],
+ LPC_FILTERORDER*sizeof(float));
+ }
+
diff --git a/jni/pjproject-android/.svn/pristine/f7/f7a6f9a3e9ddab95313e9a9189ec706cac65d234.svn-base b/jni/pjproject-android/.svn/pristine/f7/f7a6f9a3e9ddab95313e9a9189ec706cac65d234.svn-base
new file mode 100644
index 0000000..71392cc
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f7/f7a6f9a3e9ddab95313e9a9189ec706cac65d234.svn-base
@@ -0,0 +1,86 @@
+/* Copyright (C) 2007 Jean-Marc Valin
+
+ File: testresample.c
+ Testing the resampling code
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include "speex/speex_resampler.h"
+#include <math.h>
+#include <stdlib.h>
+
+#define NN 256
+
+int main()
+{
+ spx_uint32_t i;
+ short *in;
+ short *out;
+ float *fin, *fout;
+ int count = 0;
+ SpeexResamplerState *st = speex_resampler_init(1, 8000, 12000, 10, NULL);
+ speex_resampler_set_rate(st, 96000, 44100);
+ speex_resampler_skip_zeros(st);
+
+ in = malloc(NN*sizeof(short));
+ out = malloc(2*NN*sizeof(short));
+ fin = malloc(NN*sizeof(float));
+ fout = malloc(2*NN*sizeof(float));
+ while (1)
+ {
+ spx_uint32_t in_len;
+ spx_uint32_t out_len;
+ fread(in, sizeof(short), NN, stdin);
+ if (feof(stdin))
+ break;
+ for (i=0;i<NN;i++)
+ fin[i]=in[i];
+ in_len = NN;
+ out_len = 2*NN;
+ /*if (count==2)
+ speex_resampler_set_quality(st, 10);*/
+ speex_resampler_process_float(st, 0, fin, &in_len, fout, &out_len);
+ for (i=0;i<out_len;i++)
+ out[i]=floor(.5+fout[i]);
+ /*speex_warning_int("writing", out_len);*/
+ fwrite(out, sizeof(short), out_len, stdout);
+ count++;
+ }
+ speex_resampler_destroy(st);
+ free(in);
+ free(out);
+ free(fin);
+ free(fout);
+ return 0;
+}
+
diff --git a/jni/pjproject-android/.svn/pristine/f7/f7ac2ef0979704f3be98ecb2ff8d668a08637461.svn-base b/jni/pjproject-android/.svn/pristine/f7/f7ac2ef0979704f3be98ecb2ff8d668a08637461.svn-base
new file mode 100644
index 0000000..d94f590
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f7/f7ac2ef0979704f3be98ecb2ff8d668a08637461.svn-base
@@ -0,0 +1,109 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "test.h"
+#include <pjlib.h>
+
+/**
+ * \page page_pjlib_atomic_test Test: Atomic Variable
+ *
+ * This file provides implementation of \b atomic_test(). It tests the
+ * functionality of the atomic variable API.
+ *
+ * \section atomic_test_sec Scope of the Test
+ *
+ * API tested:
+ * - pj_atomic_create()
+ * - pj_atomic_get()
+ * - pj_atomic_inc()
+ * - pj_atomic_dec()
+ * - pj_atomic_set()
+ * - pj_atomic_destroy()
+ *
+ *
+ * This file is <b>pjlib-test/atomic.c</b>
+ *
+ * \include pjlib-test/atomic.c
+ */
+
+
+#if INCLUDE_ATOMIC_TEST
+
+int atomic_test(void)
+{
+ pj_pool_t *pool;
+ pj_atomic_t *atomic_var;
+ pj_status_t rc;
+
+ pool = pj_pool_create(mem, NULL, 4096, 0, NULL);
+ if (!pool)
+ return -10;
+
+ /* create() */
+ rc = pj_atomic_create(pool, 111, &atomic_var);
+ if (rc != 0) {
+ return -20;
+ }
+
+ /* get: check the value. */
+ if (pj_atomic_get(atomic_var) != 111)
+ return -30;
+
+ /* increment. */
+ pj_atomic_inc(atomic_var);
+ if (pj_atomic_get(atomic_var) != 112)
+ return -40;
+
+ /* decrement. */
+ pj_atomic_dec(atomic_var);
+ if (pj_atomic_get(atomic_var) != 111)
+ return -50;
+
+ /* set */
+ pj_atomic_set(atomic_var, 211);
+ if (pj_atomic_get(atomic_var) != 211)
+ return -60;
+
+ /* add */
+ pj_atomic_add(atomic_var, 10);
+ if (pj_atomic_get(atomic_var) != 221)
+ return -60;
+
+ /* check the value again. */
+ if (pj_atomic_get(atomic_var) != 221)
+ return -70;
+
+ /* destroy */
+ rc = pj_atomic_destroy(atomic_var);
+ if (rc != 0)
+ return -80;
+
+ pj_pool_release(pool);
+
+ return 0;
+}
+
+
+#else
+/* To prevent warning about "translation unit is empty"
+ * when this test is disabled.
+ */
+int dummy_atomic_test;
+#endif /* INCLUDE_ATOMIC_TEST */
+
diff --git a/jni/pjproject-android/.svn/pristine/f7/f7f205c97abd711dd51e5b08a40dafa62ae823c9.svn-base b/jni/pjproject-android/.svn/pristine/f7/f7f205c97abd711dd51e5b08a40dafa62ae823c9.svn-base
new file mode 100644
index 0000000..44c4b4e
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f7/f7f205c97abd711dd51e5b08a40dafa62ae823c9.svn-base
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDI9T0Pf+1gKOTOAGEpZ481Q6xfm5vz6n1+6udxzQtfPKlQrPD5
+x5im2u3tmy6ABxZeY5tCdeikBPiGlc5bRIRng6KM8kidkg3gEhwhRUxHCMWbmBpk
+z7rFERf/pWAOCqYCiy1RT8QrK+XOFoFdJhdF85UPDEUw+pHEsYetTDs9RQIDAQAB
+AoGAGV+1xQY/H7wqH8S2f/begzg3RJ8uUt8R13urm5frTqwnKNOdXbyRDshn8G9+
+sJW0gliLWxnuNP+Xrc6ujqGZIguK/yAxJ3LprAN2Ay1lW2ONyZNMquBeIY5Txhyy
+SnU7U+NQYgA3+w9T7O7YQ575TTDm2gri558jIx8t55Wo9sUCQQDtjfGZ3sYXwpxR
+MvtdtfwDxSKhf6glT6dn7/37KITBZXFy6Eb/tHrEEUuwR46g30vTd2JElCB+QExu
+4sZDt813AkEA2I/WXdGVRXtHzVivf3AnqWyXfrfAAXlBmEkgPyIPwE1+mxeNxkU7
+TRn0MOqAfbQW4+GRIYCKSBLodRnRq2iKIwJBAJLYa8DyNQH7CyYmnbwQAvlRo1ax
+0v89ff6CHD5ljar/SmH9s+XdawZIqsENet13KyhNZDGAX5WrqZPiGy1BMYECQQC1
+FREawfUfdEZF3rJgzVdcxACpZNyYXtwKipr8L28cTbBf3wIdmCZOAjW98VgfxEaf
+pi3E5ca7HZRi1oQL4A4hAkEA5koHCQYl+5PDjbLtxl0VyVCpmT9BrcZ99MS+ZEaW
+2+HpKIhXrEFxePQaWbCaW7gjKmKUwC0qqu0moedqJC3mzg==
+-----END RSA PRIVATE KEY-----
diff --git a/jni/pjproject-android/.svn/pristine/f7/f7fd67abb7f878b0030bd8be2f9f617fcd1d6f08.svn-base b/jni/pjproject-android/.svn/pristine/f7/f7fd67abb7f878b0030bd8be2f9f617fcd1d6f08.svn-base
new file mode 100644
index 0000000..85a6efb
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f7/f7fd67abb7f878b0030bd8be2f9f617fcd1d6f08.svn-base
@@ -0,0 +1,805 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/types.h>
+#include <pjmedia/alaw_ulaw.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/frame.h>
+#include <pjmedia/silencedet.h>
+#include <pj/array.h>
+#include <pj/assert.h>
+#include <pj/lock.h>
+#include <pj/log.h>
+#include <pj/os.h>
+#include <pj/pool.h>
+
+#include "echo_internal.h"
+
+#define THIS_FILE "echo_suppress.c"
+
+/* Maximum float constant */
+#define MAX_FLOAT (float)1.701411e38
+
+/* The effective learn duration (in seconds) before we declare that learning
+ * is complete. The actual learning duration itself may be longer depending
+ * on the conversation pattern (e.g. we can't detect echo if speaker is only
+ * playing silence).
+ */
+#define MAX_CALC_DURATION_SEC 3
+
+/* The internal audio segment length, in milliseconds. 10ms shold be good
+ * and no need to change it.
+ */
+#define SEGMENT_PTIME 10
+
+/* The length of the template signal in milliseconds. The longer the template,
+ * the better correlation will be found, at the expense of more processing
+ * and longer learning time.
+ */
+#define TEMPLATE_PTIME 200
+
+/* How long to look back in the past to see if either mic or speaker is
+ * active.
+ */
+#define SIGNAL_LOOKUP_MSEC 200
+
+/* The minimum level value to be considered as talking, in uLaw complement
+ * (0-255).
+ */
+#define MIN_SIGNAL_ULAW 35
+
+/* The period (in seconds) on which the ES will analize it's effectiveness,
+ * and it may trigger soft-reset to force recalculation.
+ */
+#define CHECK_PERIOD 30
+
+/* Maximum signal level of average echo residue (in uLaw complement). When
+ * the residue value exceeds this value, we force the ES to re-learn.
+ */
+#define MAX_RESIDUE 2.5
+
+
+#if 0
+# define TRACE_(expr) PJ_LOG(5,expr)
+#else
+# define TRACE_(expr)
+#endif
+
+PJ_INLINE(float) FABS(float val)
+{
+ if (val < 0)
+ return -val;
+ else
+ return val;
+}
+
+
+#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0
+ typedef float pj_ufloat_t;
+# define pj_ufloat_from_float(f) (f)
+# define pj_ufloat_mul_u(val1, f) ((val1) * (f))
+# define pj_ufloat_mul_i(val1, f) ((val1) * (f))
+#else
+ typedef pj_uint32_t pj_ufloat_t;
+
+ pj_ufloat_t pj_ufloat_from_float(float f)
+ {
+ return (pj_ufloat_t)(f * 65536);
+ }
+
+ unsigned pj_ufloat_mul_u(unsigned val1, pj_ufloat_t val2)
+ {
+ return (val1 * val2) >> 16;
+ }
+
+ int pj_ufloat_mul_i(int val1, pj_ufloat_t val2)
+ {
+ return (val1 * (pj_int32_t)val2) >> 16;
+ }
+#endif
+
+
+/* Conversation state */
+typedef enum talk_state
+{
+ ST_NULL,
+ ST_LOCAL_TALK,
+ ST_REM_SILENT,
+ ST_DOUBLETALK,
+ ST_REM_TALK
+} talk_state_t;
+
+const char *state_names[] =
+{
+ "Null",
+ "local talking",
+ "remote silent",
+ "doubletalk",
+ "remote talking"
+};
+
+
+/* Description:
+
+ The echo suppressor tries to find the position of echoed signal by looking
+ at the correlation between signal played to the speaker (played signal)
+ and the signal captured from the microphone (recorded signal).
+
+ To do this, it first divides the frames (from mic and speaker) into
+ segments, calculate the audio level of the segment, and save the level
+ information in the playback and record history (play_hist and rec_hist
+ respectively).
+
+ In the history, the newest element (depicted as "t0" in the diagram belo)
+ is put in the last position of the array.
+
+ The record history size is as large as the template size (tmpl_cnt), since
+ we will use the record history as the template to find the best matching
+ position in the playback history.
+
+ Here is the record history buffer:
+
+ <--templ_cnt-->
+ +-------------+
+ | rec_hist |
+ +-------------+
+ t-templ_cnt......t0
+
+ As you can see, the newest frame ("t0") is put as the last element in the
+ array.
+
+ The playback history size is larger than record history, since we need to
+ find the matching pattern in the past. The playback history size is
+ "templ_cnt + tail_cnt", where "tail_cnt" is the number of segments equal
+ to the maximum tail length. The maximum tail length is set when the ES
+ is created.
+
+ Here is the playback history buffer:
+
+ <-----tail_cnt-----> <--templ_cnt-->
+ +-------------------+--------------+
+ | play_hist |
+ +-------------------+--------------+
+ t-play_hist_cnt...t-templ_cnt.......t0
+
+
+
+ Learning:
+
+ During the processing, the ES calculates the following values:
+ - the correlation value, that is how similar the playback signal compared
+ to the mic signal. The lower the correlation value the better (i.e. more
+ similar) the signal is. The correlation value is done over the template
+ duration.
+ - the gain scaling factor, that is the ratio between mic signal and
+ speaker signal. The ES calculates both the minimum and average ratios.
+
+ The ES calculates both the values above for every tail position in the
+ playback history. The values are saved in arrays below:
+
+ <-----tail_cnt----->
+ +-------------------+
+ | corr_sum |
+ +-------------------+
+ | min_factor |
+ +-------------------+
+ | avg_factor |
+ +-------------------+
+
+ At the end of processing, the ES iterates through the correlation array and
+ picks the tail index with the lowest corr_sum value. This is the position
+ where echo is most likely to be found.
+
+
+ Processing:
+
+ Once learning is done, the ES will change the level of the mic signal
+ depending on the state of the conversation and according to the ratio that
+ has been found in the learning phase above.
+
+ */
+
+/*
+ * The simple echo suppresor state
+ */
+typedef struct echo_supp
+{
+ unsigned clock_rate; /* Clock rate. */
+ pj_uint16_t samples_per_frame; /* Frame length in samples */
+ pj_uint16_t samples_per_segment;/* Segment length in samples */
+ pj_uint16_t tail_ms; /* Tail length in milliseconds */
+ pj_uint16_t tail_samples; /* Tail length in samples. */
+
+ pj_bool_t learning; /* Are we still learning yet? */
+ talk_state_t talk_state; /* Current talking state */
+ int tail_index; /* Echo location, -1 if not found */
+
+ unsigned max_calc; /* # of calc before learning complete.
+ (see MAX_CALC_DURATION_SEC) */
+ unsigned calc_cnt; /* Number of calculations so far */
+
+ unsigned update_cnt; /* # of updates */
+ unsigned templ_cnt; /* Template length, in # of segments */
+ unsigned tail_cnt; /* Tail length, in # of segments */
+ unsigned play_hist_cnt; /* # of segments in play_hist */
+ pj_uint16_t *play_hist; /* Array of playback levels */
+ pj_uint16_t *rec_hist; /* Array of rec levels */
+
+ float *corr_sum; /* Array of corr for each tail pos. */
+ float *tmp_corr; /* Temporary corr array calculation */
+ float best_corr; /* Best correlation so far. */
+
+ unsigned sum_rec_level; /* Running sum of level in rec_hist */
+ float rec_corr; /* Running corr in rec_hist. */
+
+ unsigned sum_play_level0; /* Running sum of level for first pos */
+ float play_corr0; /* Running corr for first pos . */
+
+ float *min_factor; /* Array of minimum scaling factor */
+ float *avg_factor; /* Array of average scaling factor */
+ float *tmp_factor; /* Array to store provisional result */
+
+ unsigned running_cnt; /* Running duration in # of frames */
+ float residue; /* Accummulated echo residue. */
+ float last_factor; /* Last factor applied to mic signal */
+} echo_supp;
+
+
+
+/*
+ * Create.
+ */
+PJ_DEF(pj_status_t) echo_supp_create( pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned tail_ms,
+ unsigned options,
+ void **p_state )
+{
+ echo_supp *ec;
+
+ PJ_UNUSED_ARG(channel_count);
+ PJ_UNUSED_ARG(options);
+
+ PJ_ASSERT_RETURN(samples_per_frame >= SEGMENT_PTIME * clock_rate / 1000,
+ PJ_ENOTSUP);
+
+ ec = PJ_POOL_ZALLOC_T(pool, struct echo_supp);
+ ec->clock_rate = clock_rate;
+ ec->samples_per_frame = (pj_uint16_t)samples_per_frame;
+ ec->samples_per_segment = (pj_uint16_t)(SEGMENT_PTIME * clock_rate / 1000);
+ ec->tail_ms = (pj_uint16_t)tail_ms;
+ ec->tail_samples = (pj_uint16_t)(tail_ms * clock_rate / 1000);
+
+ ec->templ_cnt = TEMPLATE_PTIME / SEGMENT_PTIME;
+ ec->tail_cnt = (pj_uint16_t)(tail_ms / SEGMENT_PTIME);
+ ec->play_hist_cnt = (pj_uint16_t)(ec->tail_cnt+ec->templ_cnt);
+
+ ec->max_calc = (pj_uint16_t)(MAX_CALC_DURATION_SEC * clock_rate /
+ ec->samples_per_segment);
+
+ ec->rec_hist = (pj_uint16_t*)
+ pj_pool_alloc(pool, ec->templ_cnt *
+ sizeof(ec->rec_hist[0]));
+
+ /* Note: play history has twice number of elements */
+ ec->play_hist = (pj_uint16_t*)
+ pj_pool_alloc(pool, ec->play_hist_cnt *
+ sizeof(ec->play_hist[0]));
+
+ ec->corr_sum = (float*)
+ pj_pool_alloc(pool, ec->tail_cnt *
+ sizeof(ec->corr_sum[0]));
+ ec->tmp_corr = (float*)
+ pj_pool_alloc(pool, ec->tail_cnt *
+ sizeof(ec->tmp_corr[0]));
+ ec->min_factor = (float*)
+ pj_pool_alloc(pool, ec->tail_cnt *
+ sizeof(ec->min_factor[0]));
+ ec->avg_factor = (float*)
+ pj_pool_alloc(pool, ec->tail_cnt *
+ sizeof(ec->avg_factor[0]));
+ ec->tmp_factor = (float*)
+ pj_pool_alloc(pool, ec->tail_cnt *
+ sizeof(ec->tmp_factor[0]));
+ echo_supp_reset(ec);
+
+ *p_state = ec;
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Destroy.
+ */
+PJ_DEF(pj_status_t) echo_supp_destroy(void *state)
+{
+ PJ_UNUSED_ARG(state);
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Hard reset
+ */
+PJ_DEF(void) echo_supp_reset(void *state)
+{
+ unsigned i;
+ echo_supp *ec = (echo_supp*) state;
+
+ pj_bzero(ec->rec_hist, ec->templ_cnt * sizeof(ec->rec_hist[0]));
+ pj_bzero(ec->play_hist, ec->play_hist_cnt * sizeof(ec->play_hist[0]));
+
+ for (i=0; i<ec->tail_cnt; ++i) {
+ ec->corr_sum[i] = ec->avg_factor[i] = 0;
+ ec->min_factor[i] = MAX_FLOAT;
+ }
+
+ ec->update_cnt = 0;
+ ec->calc_cnt = 0;
+ ec->learning = PJ_TRUE;
+ ec->tail_index = -1;
+ ec->best_corr = MAX_FLOAT;
+ ec->talk_state = ST_NULL;
+ ec->last_factor = 1.0;
+ ec->residue = 0;
+ ec->running_cnt = 0;
+ ec->sum_rec_level = ec->sum_play_level0 = 0;
+ ec->rec_corr = ec->play_corr0 = 0;
+}
+
+/*
+ * Soft reset to force the EC to re-learn without having to discard all
+ * rec and playback history.
+ */
+PJ_DEF(void) echo_supp_soft_reset(void *state)
+{
+ unsigned i;
+
+ echo_supp *ec = (echo_supp*) state;
+
+ for (i=0; i<ec->tail_cnt; ++i) {
+ ec->corr_sum[i] = 0;
+ }
+
+ ec->update_cnt = 0;
+ ec->calc_cnt = 0;
+ ec->learning = PJ_TRUE;
+ ec->best_corr = MAX_FLOAT;
+ ec->residue = 0;
+ ec->running_cnt = 0;
+ ec->sum_rec_level = ec->sum_play_level0 = 0;
+ ec->rec_corr = ec->play_corr0 = 0;
+
+ PJ_LOG(4,(THIS_FILE, "Echo suppressor soft reset. Re-learning.."));
+}
+
+
+/* Set state */
+static void echo_supp_set_state(echo_supp *ec, talk_state_t state,
+ unsigned level)
+{
+ PJ_UNUSED_ARG(level);
+
+ if (state != ec->talk_state) {
+ TRACE_((THIS_FILE, "[%03d.%03d] %s --> %s, level=%u",
+ (ec->update_cnt * SEGMENT_PTIME / 1000),
+ ((ec->update_cnt * SEGMENT_PTIME) % 1000),
+ state_names[ec->talk_state],
+ state_names[state], level));
+ ec->talk_state = state;
+ }
+}
+
+/*
+ * Update EC state
+ */
+static void echo_supp_update(echo_supp *ec, pj_int16_t *rec_frm,
+ const pj_int16_t *play_frm)
+{
+ int prev_index;
+ unsigned i, j, frm_level, sum_play_level, ulaw;
+ pj_uint16_t old_rec_frm_level, old_play_frm_level;
+ float play_corr;
+
+ ++ec->update_cnt;
+ if (ec->update_cnt > 0x7FFFFFFF)
+ ec->update_cnt = 0x7FFFFFFF; /* Detect overflow */
+
+ /* Calculate current play frame level */
+ frm_level = pjmedia_calc_avg_signal(play_frm, ec->samples_per_segment);
+ ++frm_level; /* to avoid division by zero */
+
+ /* Save the oldest frame level for later */
+ old_play_frm_level = ec->play_hist[0];
+
+ /* Push current frame level to the back of the play history */
+ pj_array_erase(ec->play_hist, sizeof(pj_uint16_t), ec->play_hist_cnt, 0);
+ ec->play_hist[ec->play_hist_cnt-1] = (pj_uint16_t) frm_level;
+
+ /* Calculate level of current mic frame */
+ frm_level = pjmedia_calc_avg_signal(rec_frm, ec->samples_per_segment);
+ ++frm_level; /* to avoid division by zero */
+
+ /* Save the oldest frame level for later */
+ old_rec_frm_level = ec->rec_hist[0];
+
+ /* Push to the back of the rec history */
+ pj_array_erase(ec->rec_hist, sizeof(pj_uint16_t), ec->templ_cnt, 0);
+ ec->rec_hist[ec->templ_cnt-1] = (pj_uint16_t) frm_level;
+
+
+ /* Can't do the calc until the play history is full. */
+ if (ec->update_cnt < ec->play_hist_cnt)
+ return;
+
+ /* Skip if learning is done */
+ if (!ec->learning)
+ return;
+
+
+ /* Calculate rec signal pattern */
+ if (ec->sum_rec_level == 0) {
+ /* Buffer has just been filled up, do full calculation */
+ ec->rec_corr = 0;
+ ec->sum_rec_level = 0;
+ for (i=0; i < ec->templ_cnt-1; ++i) {
+ float corr;
+ corr = (float)ec->rec_hist[i+1] / ec->rec_hist[i];
+ ec->rec_corr += corr;
+ ec->sum_rec_level += ec->rec_hist[i];
+ }
+ ec->sum_rec_level += ec->rec_hist[i];
+ } else {
+ /* Update from previous calculation */
+ ec->sum_rec_level = ec->sum_rec_level - old_rec_frm_level +
+ ec->rec_hist[ec->templ_cnt-1];
+ ec->rec_corr = ec->rec_corr - ((float)ec->rec_hist[0] /
+ old_rec_frm_level) +
+ ((float)ec->rec_hist[ec->templ_cnt-1] /
+ ec->rec_hist[ec->templ_cnt-2]);
+ }
+
+ /* Iterate through the play history and calculate the signal correlation
+ * for every tail position in the play_hist. Save the result in temporary
+ * array since we may bail out early if the conversation state is not good
+ * to detect echo.
+ */
+ /*
+ * First phase: do full calculation for the first position
+ */
+ if (ec->sum_play_level0 == 0) {
+ /* Buffer has just been filled up, do full calculation */
+ sum_play_level = 0;
+ play_corr = 0;
+ for (j=0; j<ec->templ_cnt-1; ++j) {
+ float corr;
+ corr = (float)ec->play_hist[j+1] / ec->play_hist[j];
+ play_corr += corr;
+ sum_play_level += ec->play_hist[j];
+ }
+ sum_play_level += ec->play_hist[j];
+ ec->sum_play_level0 = sum_play_level;
+ ec->play_corr0 = play_corr;
+ } else {
+ /* Update from previous calculation */
+ ec->sum_play_level0 = ec->sum_play_level0 - old_play_frm_level +
+ ec->play_hist[ec->templ_cnt-1];
+ ec->play_corr0 = ec->play_corr0 - ((float)ec->play_hist[0] /
+ old_play_frm_level) +
+ ((float)ec->play_hist[ec->templ_cnt-1] /
+ ec->play_hist[ec->templ_cnt-2]);
+ sum_play_level = ec->sum_play_level0;
+ play_corr = ec->play_corr0;
+ }
+ ec->tmp_corr[0] = FABS(play_corr - ec->rec_corr);
+ ec->tmp_factor[0] = (float)ec->sum_rec_level / sum_play_level;
+
+ /* Bail out if remote isn't talking */
+ ulaw = pjmedia_linear2ulaw(sum_play_level/ec->templ_cnt) ^ 0xFF;
+ if (ulaw < MIN_SIGNAL_ULAW) {
+ echo_supp_set_state(ec, ST_REM_SILENT, ulaw);
+ return;
+ }
+ /* Bail out if local user is talking */
+ if (ec->sum_rec_level >= sum_play_level) {
+ echo_supp_set_state(ec, ST_LOCAL_TALK, ulaw);
+ return;
+ }
+
+ /*
+ * Second phase: do incremental calculation for the rest of positions
+ */
+ for (i=1; i < ec->tail_cnt; ++i) {
+ unsigned end;
+
+ end = i + ec->templ_cnt;
+
+ sum_play_level = sum_play_level - ec->play_hist[i-1] +
+ ec->play_hist[end-1];
+ play_corr = play_corr - ((float)ec->play_hist[i]/ec->play_hist[i-1]) +
+ ((float)ec->play_hist[end-1]/ec->play_hist[end-2]);
+
+ /* Bail out if remote isn't talking */
+ ulaw = pjmedia_linear2ulaw(sum_play_level/ec->templ_cnt) ^ 0xFF;
+ if (ulaw < MIN_SIGNAL_ULAW) {
+ echo_supp_set_state(ec, ST_REM_SILENT, ulaw);
+ return;
+ }
+
+ /* Bail out if local user is talking */
+ if (ec->sum_rec_level >= sum_play_level) {
+ echo_supp_set_state(ec, ST_LOCAL_TALK, ulaw);
+ return;
+ }
+
+#if 0
+ // disabled: not a good idea if mic throws out loud echo
+ /* Also bail out if we suspect there's a doubletalk */
+ ulaw = pjmedia_linear2ulaw(ec->sum_rec_level/ec->templ_cnt) ^ 0xFF;
+ if (ulaw > MIN_SIGNAL_ULAW) {
+ echo_supp_set_state(ec, ST_DOUBLETALK, ulaw);
+ return;
+ }
+#endif
+
+ /* Calculate correlation and save to temporary array */
+ ec->tmp_corr[i] = FABS(play_corr - ec->rec_corr);
+
+ /* Also calculate the gain factor between mic and speaker level */
+ ec->tmp_factor[i] = (float)ec->sum_rec_level / sum_play_level;
+ pj_assert(ec->tmp_factor[i] < 1);
+ }
+
+ /* We seem to have good signal, we can update the EC state */
+ echo_supp_set_state(ec, ST_REM_TALK, MIN_SIGNAL_ULAW);
+
+ /* Accummulate the correlation value to the history and at the same
+ * time find the tail index of the best correlation.
+ */
+ prev_index = ec->tail_index;
+ for (i=1; i<ec->tail_cnt-1; ++i) {
+ float *p = &ec->corr_sum[i], sum;
+
+ /* Accummulate correlation value for this tail position */
+ ec->corr_sum[i] += ec->tmp_corr[i];
+
+ /* Update the min and avg gain factor for this tail position */
+ if (ec->tmp_factor[i] < ec->min_factor[i])
+ ec->min_factor[i] = ec->tmp_factor[i];
+ ec->avg_factor[i] = ((ec->avg_factor[i] * ec->tail_cnt) +
+ ec->tmp_factor[i]) /
+ (ec->tail_cnt + 1);
+
+ /* To get the best correlation, also include the correlation
+ * value of the neighbouring tail locations.
+ */
+ sum = *(p-1) + (*p)*2 + *(p+1);
+ //sum = *p;
+
+ /* See if we have better correlation value */
+ if (sum < ec->best_corr) {
+ ec->tail_index = i;
+ ec->best_corr = sum;
+ }
+ }
+
+ if (ec->tail_index != prev_index) {
+ unsigned duration;
+ int imin, iavg;
+
+ duration = ec->update_cnt * SEGMENT_PTIME;
+ imin = (int)(ec->min_factor[ec->tail_index] * 1000);
+ iavg = (int)(ec->avg_factor[ec->tail_index] * 1000);
+
+ PJ_LOG(4,(THIS_FILE,
+ "Echo suppressor updated at t=%03d.%03ds, echo tail=%d msec"
+ ", factor min/avg=%d.%03d/%d.%03d",
+ (duration/1000), (duration%1000),
+ (ec->tail_cnt-ec->tail_index) * SEGMENT_PTIME,
+ imin/1000, imin%1000,
+ iavg/1000, iavg%1000));
+
+ }
+
+ ++ec->calc_cnt;
+
+ if (ec->calc_cnt > ec->max_calc) {
+ unsigned duration;
+ int imin, iavg;
+
+
+ ec->learning = PJ_FALSE;
+ ec->running_cnt = 0;
+
+ duration = ec->update_cnt * SEGMENT_PTIME;
+ imin = (int)(ec->min_factor[ec->tail_index] * 1000);
+ iavg = (int)(ec->avg_factor[ec->tail_index] * 1000);
+
+ PJ_LOG(4,(THIS_FILE,
+ "Echo suppressor learning done at t=%03d.%03ds, tail=%d ms"
+ ", factor min/avg=%d.%03d/%d.%03d",
+ (duration/1000), (duration%1000),
+ (ec->tail_cnt-ec->tail_index) * SEGMENT_PTIME,
+ imin/1000, imin%1000,
+ iavg/1000, iavg%1000));
+ }
+
+}
+
+
+/* Amplify frame */
+static void amplify_frame(pj_int16_t *frm, unsigned length,
+ pj_ufloat_t factor)
+{
+ unsigned i;
+
+ for (i=0; i<length; ++i) {
+ frm[i] = (pj_int16_t)pj_ufloat_mul_i(frm[i], factor);
+ }
+}
+
+/*
+ * Perform echo cancellation.
+ */
+PJ_DEF(pj_status_t) echo_supp_cancel_echo( void *state,
+ pj_int16_t *rec_frm,
+ const pj_int16_t *play_frm,
+ unsigned options,
+ void *reserved )
+{
+ unsigned i, N;
+ echo_supp *ec = (echo_supp*) state;
+
+ PJ_UNUSED_ARG(options);
+ PJ_UNUSED_ARG(reserved);
+
+ /* Calculate number of segments. This should be okay even if
+ * samples_per_frame is not a multiply of samples_per_segment, since
+ * we only calculate level.
+ */
+ N = ec->samples_per_frame / ec->samples_per_segment;
+ pj_assert(N>0);
+ for (i=0; i<N; ++i) {
+ unsigned pos = i * ec->samples_per_segment;
+ echo_supp_update(ec, rec_frm+pos, play_frm+pos);
+ }
+
+ if (ec->tail_index < 0) {
+ /* Not ready */
+ } else {
+ unsigned lookup_cnt, rec_level=0, play_level=0;
+ unsigned tail_cnt;
+ float factor;
+
+ /* How many previous segments to lookup */
+ lookup_cnt = SIGNAL_LOOKUP_MSEC / SEGMENT_PTIME;
+ if (lookup_cnt > ec->templ_cnt)
+ lookup_cnt = ec->templ_cnt;
+
+ /* Lookup in recording history to get maximum mic level, to see
+ * if local user is currently talking
+ */
+ for (i=ec->templ_cnt - lookup_cnt; i < ec->templ_cnt; ++i) {
+ if (ec->rec_hist[i] > rec_level)
+ rec_level = ec->rec_hist[i];
+ }
+ rec_level = pjmedia_linear2ulaw(rec_level) ^ 0xFF;
+
+ /* Calculate the detected tail length, in # of segments */
+ tail_cnt = (ec->tail_cnt - ec->tail_index);
+
+ /* Lookup in playback history to get max speaker level, to see
+ * if remote user is currently talking
+ */
+ for (i=ec->play_hist_cnt -lookup_cnt -tail_cnt;
+ i<ec->play_hist_cnt-tail_cnt; ++i)
+ {
+ if (ec->play_hist[i] > play_level)
+ play_level = ec->play_hist[i];
+ }
+ play_level = pjmedia_linear2ulaw(play_level) ^ 0xFF;
+
+ if (rec_level >= MIN_SIGNAL_ULAW) {
+ if (play_level < MIN_SIGNAL_ULAW) {
+ /* Mic is talking, speaker is idle. Let mic signal pass as is.
+ */
+ factor = 1.0;
+ echo_supp_set_state(ec, ST_LOCAL_TALK, rec_level);
+ } else if (rec_level > play_level) {
+ /* Seems that both are talking. Scale the mic signal
+ * down a little bit to reduce echo, while allowing both
+ * parties to talk at the same time.
+ */
+ factor = (float)(ec->avg_factor[ec->tail_index] * 2);
+ echo_supp_set_state(ec, ST_DOUBLETALK, rec_level);
+ } else {
+ /* Speaker is active, but we've picked up large signal in
+ * the microphone. Assume that this is an echo, so bring
+ * the level down to minimum too.
+ */
+ factor = ec->min_factor[ec->tail_index] / 2;
+ echo_supp_set_state(ec, ST_REM_TALK, play_level);
+ }
+ } else {
+ if (play_level < MIN_SIGNAL_ULAW) {
+ /* Both mic and speaker seems to be idle. Also scale the
+ * mic signal down with average factor to reduce low power
+ * echo.
+ */
+ factor = ec->avg_factor[ec->tail_index] * 3 / 2;
+ echo_supp_set_state(ec, ST_REM_SILENT, rec_level);
+ } else {
+ /* Mic is idle, but there's something playing in speaker.
+ * Scale the mic down to minimum
+ */
+ factor = ec->min_factor[ec->tail_index] / 2;
+ echo_supp_set_state(ec, ST_REM_TALK, play_level);
+ }
+ }
+
+ /* Smoothen the transition */
+ if (factor >= ec->last_factor)
+ factor = (factor + ec->last_factor) / 2;
+ else
+ factor = (factor + ec->last_factor*19) / 20;
+
+ /* Amplify frame */
+ amplify_frame(rec_frm, ec->samples_per_frame,
+ pj_ufloat_from_float(factor));
+ ec->last_factor = factor;
+
+ if (ec->talk_state == ST_REM_TALK) {
+ unsigned level, recalc_cnt;
+
+ /* Get the adjusted frame signal level */
+ level = pjmedia_calc_avg_signal(rec_frm, ec->samples_per_frame);
+ level = pjmedia_linear2ulaw(level) ^ 0xFF;
+
+ /* Accumulate average echo residue to see the ES effectiveness */
+ ec->residue = ((ec->residue * ec->running_cnt) + level) /
+ (ec->running_cnt + 1);
+
+ ++ec->running_cnt;
+
+ /* Check if we need to re-learn */
+ recalc_cnt = CHECK_PERIOD * ec->clock_rate / ec->samples_per_frame;
+ if (ec->running_cnt > recalc_cnt) {
+ int iresidue;
+
+ iresidue = (int)(ec->residue*1000);
+
+ PJ_LOG(5,(THIS_FILE, "Echo suppressor residue = %d.%03d",
+ iresidue/1000, iresidue%1000));
+
+ if (ec->residue > MAX_RESIDUE && !ec->learning) {
+ echo_supp_soft_reset(ec);
+ ec->residue = 0;
+ } else {
+ ec->running_cnt = 0;
+ ec->residue = 0;
+ }
+ }
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
diff --git a/jni/pjproject-android/.svn/pristine/f7/f7fee6d53a2bcf4194b52fdd5ca4f7c8953179f1.svn-base b/jni/pjproject-android/.svn/pristine/f7/f7fee6d53a2bcf4194b52fdd5ca4f7c8953179f1.svn-base
new file mode 100644
index 0000000..c607de6
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/f7/f7fee6d53a2bcf4194b52fdd5ca4f7c8953179f1.svn-base
@@ -0,0 +1,26 @@
+# $Id$
+import inc_sip as sip
+import inc_sdp as sdp
+
+sdp = \
+"""
+v=0
+o=- 0 0 IN IP4 127.0.0.1
+s=pjmedia
+c=IN IP4 127.0.0.1
+t=0 0
+m=audio 4000 RTP/AVP 0 101
+a=rtpmap:0 PCMU/8000
+a=sendrecv
+a=rtpmap:101 telephone-event/8000
+a=fmtp:101 0-15
+"""
+
+pjsua_args = "--null-audio --auto-answer 200 --timer-min-se 2000 --timer-se 2000"
+extra_headers = "Supported: timer\nSession-Expires: 1800\n"
+include = ["Min-SE:\s*2000"]
+exclude = []
+sendto_cfg = sip.SendtoCfg("Session Timer SE too small", pjsua_args, sdp, 422,
+ extra_headers=extra_headers,
+ resp_inc=include, resp_exc=exclude)
+