* #36737: switch back to svn repo, remove assert in sip_transaction.c
diff --git a/jni/pjproject-android/.svn/pristine/b8/b8357fb3910068ee29876853cc8eab21e4c585a9.svn-base b/jni/pjproject-android/.svn/pristine/b8/b8357fb3910068ee29876853cc8eab21e4c585a9.svn-base
new file mode 100644
index 0000000..37c9712
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/b8/b8357fb3910068ee29876853cc8eab21e4c585a9.svn-base
@@ -0,0 +1,30 @@
+# $Id$
+#
+import inc_const as const
+
+PJSUA = ["--null-audio",    # UA0
+	 "--null-audio",    # UA1
+	 "--null-audio"	    # UA2
+	]
+
+PJSUA_EXPECTS = [
+		 # A calls B
+		 [0, "", "m"],
+		 [0, "", "$PJSUA_URI[1]"],
+		 [0, const.STATE_CALLING, ""],
+		 [1, const.EVENT_INCOMING_CALL, "a"],
+		 [1, "", "200"],
+		 [0, const.STATE_CONFIRMED, ""],
+		 [1, const.STATE_CONFIRMED, ""],
+
+		 # B transfer A to C
+		 [1, "", "x"],
+		 [1, "", "$PJSUA_URI[2]"],
+		 [0, const.STATE_CALLING, ""],
+		 [2, const.EVENT_INCOMING_CALL, "a"],
+		 [2, "", "200"],
+		 [0, const.MEDIA_ACTIVE, ""],
+		 [2, const.MEDIA_ACTIVE, ""],
+		 [1, "call transfered successfully", ""],
+		 [1, const.STATE_DISCONNECTED, ""]
+		]
diff --git a/jni/pjproject-android/.svn/pristine/b8/b89fe830537189f1d79eb90158e4ecf91364d52b.svn-base b/jni/pjproject-android/.svn/pristine/b8/b89fe830537189f1d79eb90158e4ecf91364d52b.svn-base
new file mode 100644
index 0000000..a0fed9c
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/b8/b89fe830537189f1d79eb90158e4ecf91364d52b.svn-base
@@ -0,0 +1,218 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2008-2011 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 __PJMEDIA_VIDEODEV_CONFIG_H__
+#define __PJMEDIA_VIDEODEV_CONFIG_H__
+
+/**
+ * @file config.h
+ * @brief Video config.
+ */
+#include <pjmedia/types.h>
+#include <pj/pool.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup video_device_api Video Device API
+ * @brief PJMEDIA video device abstraction API.
+ */
+
+/**
+ * @defgroup s1_video_device_config Compile time configurations
+ * @ingroup video_device_api
+ * @brief Compile time configurations
+ * @{
+ */
+
+/**
+ * This setting controls the maximum number of formats that can be
+ * supported by a video device.
+ *
+ * Default: 16
+ */
+#ifndef PJMEDIA_VID_DEV_INFO_FMT_CNT
+#   define PJMEDIA_VID_DEV_INFO_FMT_CNT 16
+#endif
+
+
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+
+/**
+ * This setting controls whether SDL support should be included.
+ *
+ * Default: 0 (or detected by configure)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_SDL
+#   define PJMEDIA_VIDEO_DEV_HAS_SDL		0
+#   define PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL	0
+#endif
+
+
+/**
+ * This setting controls whether QT support should be included.
+ *
+ * Default: 0 (or detected by configure)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_QT
+#   define PJMEDIA_VIDEO_DEV_HAS_QT		0
+#endif
+
+
+/**
+ * This setting controls whether IOS support should be included.
+ *
+ * Default: 0 (or detected by configure)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_IOS
+#   define PJMEDIA_VIDEO_DEV_HAS_IOS		0
+#endif
+
+
+/**
+ * This setting controls whether Direct Show support should be included.
+ *
+ * Default: 0 (unfinished)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_DSHOW
+#   define PJMEDIA_VIDEO_DEV_HAS_DSHOW		0 //PJ_WIN32
+#endif
+
+
+/**
+ * This setting controls whether colorbar source support should be included.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC
+#   define PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC	1
+#endif
+
+
+/**
+ * This setting controls whether ffmpeg support should be included.
+ *
+ * Default: 0 (unfinished)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_FFMPEG
+#   define PJMEDIA_VIDEO_DEV_HAS_FFMPEG	        0
+#endif
+
+
+/**
+ * Video4Linux2
+ *
+ * Default: 0 (or detected by configure)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_V4L2
+#   define PJMEDIA_VIDEO_DEV_HAS_V4L2		0
+#endif
+
+
+/**
+ * Enable support for AVI player virtual capture device.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_AVI
+#   define PJMEDIA_VIDEO_DEV_HAS_AVI		1
+#endif
+
+/**
+ * Specify the SDL library name to be linked with Visual Studio project. 
+ * By default, the name is autodetected based on SDL version ("sdl.lib" or 
+ * "sdl2.lib"), but application may explicitly specify the library name if this 
+ * autodetection fails. Common names are: "sdl2.lib" or "sdl.lib".
+ *
+ * Default: undeclared.
+ */
+#ifndef PJMEDIA_SDL_LIB
+#   undef PJMEDIA_SDL_LIB
+#endif
+
+#endif /* defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) */
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif	/* __PJMEDIA_VIDEODEV_CONFIG_H__ */
+
+/*
+ --------------------- DOCUMENTATION FOLLOWS ---------------------------
+ */
+
+/**
+ * @addtogroup video_device_api Video Device API
+ * @{
+
+PJMEDIA Video Device API is a cross-platform video API appropriate for use with
+VoIP applications and many other types of video streaming applications. 
+
+The API abstracts many different video API's on various platforms, such as:
+ - native Direct Show video for Win32 and Windows Mobile devices
+ - null-video implementation
+ - and more to be implemented in the future
+
+The Video Device API/library is an evolution from PJMEDIA @ref PJMED_SND and 
+contains many enhancements:
+
+ - Forward compatibility:
+\n
+   The new API has been designed to be extensible, it will support new API's as 
+   well as new features that may be introduced in the future without breaking 
+   compatibility with applications that use this API as well as compatibility 
+   with existing device implementations. 
+
+ - Device capabilities:
+\n
+   At the heart of the API is device capabilities management, where all possible
+   video capabilities of video devices should be able to be handled in a generic
+   manner. With this framework, new capabilities that may be discovered in the 
+   future can be handled in manner without breaking existing applications. 
+
+ - Built-in features:
+\n
+   The device capabilities framework enables applications to use and control 
+   video features built-in in the device, such as:
+    - built-in formats, 
+    - etc.
+
+ - Codec support:
+\n
+   Some video devices support built-in hardware video codecs, and application
+   can use the video device in encoded mode to make use of these hardware 
+   codecs. 
+
+ - Multiple backends:
+\n
+   The new API supports multiple video backends (called factories or drivers in 
+   the code) to be active simultaneously, and video backends may be added or 
+   removed during run-time. 
+
+*/
+
+
+/**
+ * @}
+ */
+
diff --git a/jni/pjproject-android/.svn/pristine/b8/b8c50214d2dcdf6c3f6e4e11caf754d1c4ae4aa6.svn-base b/jni/pjproject-android/.svn/pristine/b8/b8c50214d2dcdf6c3f6e4e11caf754d1c4ae4aa6.svn-base
new file mode 100644
index 0000000..ddae747
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/b8/b8c50214d2dcdf6c3f6e4e11caf754d1c4ae4aa6.svn-base
@@ -0,0 +1,130 @@
+<?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="Forked INVITE, one of them require PRACK">

+  <recv request="INVITE" crlf="true">

+   <action>

+    <ereg regexp="branch=([^;]*)"

+          search_in="hdr"

+          header="Via"

+          assign_to="3"/>

+    <ereg regexp="CSeq: ([0-9a-zA-Z ]*)"

+          search_in="msg"

+          assign_to="4"/>

+   </action>

+  </recv>

+

+  <send>

+    <![CDATA[

+      SIP/2.0 100 Trying

+      [last_Via:]

+      [last_From:]

+      [last_To:];tag=[call_number]

+      [last_Call-ID:]

+      [last_CSeq:]

+    ]]>

+  </send>

+

+  <!-- Call leg 1: 180/Ringing -->

+  <send>

+    <![CDATA[

+      SIP/2.0 180 Ringing

+      [last_Via:]

+      [last_From:]

+      [last_To:];tag=1

+      [last_Call-ID:]

+      [last_CSeq:]

+      Contact: <sip:WRONG_UA@192.168.0.1>

+    ]]>

+  </send>

+

+  <!-- Call leg 2: 180/Ringing with 100rel -->

+  <send retrans="1000">

+    <![CDATA[

+      SIP/2.0 180 Ringing

+      [last_Via:]

+      [last_From:]

+      [last_To:];tag=2

+      [last_Call-ID:]

+      [last_CSeq:]

+      Require: 100rel

+      RSeq: 1

+      Contact: <sip:RIGHT_UA@[local_ip]:[local_port]>

+    ]]>

+  </send>

+

+  <!-- Expect PRACK -->

+  <recv request="PRACK"

+        optional="false"

+        rtd="true"

+        crlf="true">

+  </recv>

+

+  <!-- Send 200/OK to PRACK -->

+  <send>

+    <![CDATA[

+      SIP/2.0 200 OK

+      [last_Via:]

+      [last_From:]

+      [last_To:]

+      [last_Call-ID:]

+      [last_CSeq:]

+    ]]>

+  </send>

+

+  <!-- Send 200/OK to INVITE -->

+  <send retrans="500">

+    <![CDATA[

+      SIP/2.0 200 OK

+      Via: SIP/2.0/UDP 127.0.0.1:5080;received=127.0.0.1;rport=5080;[$3]

+      [last_From:]

+      [last_To:];tag=2

+      [last_Call-ID:]

+      [$4]

+      Contact: <sip:RIGHT_UA@[local_ip]:[local_port]>

+      Content-Type: application/sdp

+

+      v=0

+      o=- 3442013205 3442013205 IN IP4 192.168.0.13

+      s=pjsip

+      c=IN IP4 192.168.0.13

+      t=0 0

+      m=audio 4002 RTP/AVP 0

+      a=rtpmap:0 PCMU/8000

+    ]]>

+  </send>

+

+  <!-- Receive ACK -->

+  <recv request="ACK"

+        optional="false"

+        rtd="true"

+        crlf="true">

+  </recv>

+

+

+  <!-- 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/b8/b8dec17417e46456003da015bb6db50356432d2b.svn-base b/jni/pjproject-android/.svn/pristine/b8/b8dec17417e46456003da015bb6db50356432d2b.svn-base
new file mode 100644
index 0000000..24c8929
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/b8/b8dec17417e46456003da015bb6db50356432d2b.svn-base
@@ -0,0 +1,17 @@
+# $Id$
+#
+from inc_cfg import *
+
+# Call with G722 codec
+test_param = TestParam(
+		"PESQ codec G722 (RX side uses snd dev)",
+		[
+			InstanceParam("UA1", "--max-calls=1 --add-codec g722 --clock-rate 16000 --play-file wavs/input.16.wav --null-audio"),
+			InstanceParam("UA2", "--max-calls=1 --add-codec g722 --clock-rate 16000 --rec-file  wavs/tmp.16.wav   --auto-answer 200")
+		]
+		)
+
+if (HAS_SND_DEV == 0):
+	test_param.skip = True
+
+pesq_threshold = 3.7
diff --git a/jni/pjproject-android/.svn/pristine/b8/b8e315d64c31ad54a5ea71ec8d18e520859270ec.svn-base b/jni/pjproject-android/.svn/pristine/b8/b8e315d64c31ad54a5ea71ec8d18e520859270ec.svn-base
new file mode 100644
index 0000000..aaa9512
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/b8/b8e315d64c31ad54a5ea71ec8d18e520859270ec.svn-base
@@ -0,0 +1,434 @@
+/* $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-audiodev/audiodev.h>
+#include <pjmedia/delaybuf.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/os.h>
+#include <pj/log.h>
+#include <pj/string.h>
+#include <pj/unicode.h>
+#include <e32cons.h>
+
+#define THIS_FILE		"app_main.cpp"
+#define CLOCK_RATE		8000
+#define CHANNEL_COUNT		1
+#define PTIME			20
+#define SAMPLES_PER_FRAME	(CLOCK_RATE*PTIME/1000)
+#define BITS_PER_SAMPLE		16
+
+extern CConsoleBase* console;
+
+static pj_caching_pool cp;
+static pjmedia_aud_stream *strm;
+static unsigned rec_cnt, play_cnt;
+static pj_time_val t_start;
+static pjmedia_aud_param param;
+static pj_pool_t *pool;
+static pjmedia_delay_buf *delaybuf;
+static char frame_buf[256];
+
+static void copy_frame_ext(pjmedia_frame_ext *f_dst, 
+                           const pjmedia_frame_ext *f_src) 
+{
+    pj_bzero(f_dst, sizeof(*f_dst));
+    if (f_src->subframe_cnt) {
+	f_dst->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
+	for (unsigned i = 0; i < f_src->subframe_cnt; ++i) {
+	    pjmedia_frame_ext_subframe *sf;
+	    sf = pjmedia_frame_ext_get_subframe(f_src, i);
+	    pjmedia_frame_ext_append_subframe(f_dst, sf->data, sf->bitlen, 
+					      param.samples_per_frame);
+	}
+    } else {
+	f_dst->base.type = PJMEDIA_FRAME_TYPE_NONE;
+    }
+}
+
+/* Logging callback */
+static void log_writer(int level, const char *buf, unsigned len)
+{
+    static wchar_t buf16[PJ_LOG_MAX_SIZE];
+
+    PJ_UNUSED_ARG(level);
+
+    pj_ansi_to_unicode(buf, len, buf16, PJ_ARRAY_SIZE(buf16));
+
+    TPtrC16 aBuf((const TUint16*)buf16, (TInt)len);
+    console->Write(aBuf);
+}
+
+/* perror util */
+static void app_perror(const char *title, pj_status_t status)
+{
+    char errmsg[PJ_ERR_MSG_SIZE];
+    pj_strerror(status, errmsg, sizeof(errmsg));
+    PJ_LOG(1,(THIS_FILE, "Error: %s: %s", title, errmsg));
+}
+
+/* Application init */
+static pj_status_t app_init()
+{
+    unsigned i, count;
+    pj_status_t status;
+
+    /* Redirect log */
+    pj_log_set_log_func((void (*)(int,const char*,int)) &log_writer);
+    pj_log_set_decor(PJ_LOG_HAS_NEWLINE);
+    pj_log_set_level(3);
+
+    /* Init pjlib */
+    status = pj_init();
+    if (status != PJ_SUCCESS) {
+    	app_perror("pj_init()", status);
+    	return status;
+    }
+
+    pj_caching_pool_init(&cp, NULL, 0);
+
+    /* Init sound subsystem */
+    status = pjmedia_aud_subsys_init(&cp.factory);
+    if (status != PJ_SUCCESS) {
+    	app_perror("pjmedia_snd_init()", status);
+        pj_caching_pool_destroy(&cp);
+    	pj_shutdown();
+    	return status;
+    }
+
+    count = pjmedia_aud_dev_count();
+    PJ_LOG(3,(THIS_FILE, "Device count: %d", count));
+    for (i=0; i<count; ++i) {
+    	pjmedia_aud_dev_info info;
+    	pj_status_t status;
+
+    	status = pjmedia_aud_dev_get_info(i, &info);
+    	pj_assert(status == PJ_SUCCESS);
+    	PJ_LOG(3, (THIS_FILE, "%d: %s %d/%d %dHz",
+    		   i, info.name, info.input_count, info.output_count,
+    		   info.default_samples_per_sec));
+    	
+	unsigned j;
+
+	/* Print extended formats supported by this audio device */
+	PJ_LOG(3, (THIS_FILE, "   Extended formats supported:"));
+	for (j = 0; j < info.ext_fmt_cnt; ++j) {
+	    const char *fmt_name = NULL;
+	    
+	    switch (info.ext_fmt[j].id) {
+	    case PJMEDIA_FORMAT_PCMA:
+		fmt_name = "PCMA";
+		break;
+	    case PJMEDIA_FORMAT_PCMU:
+		fmt_name = "PCMU";
+		break;
+	    case PJMEDIA_FORMAT_AMR:
+		fmt_name = "AMR-NB";
+		break;
+	    case PJMEDIA_FORMAT_G729:
+		fmt_name = "G729";
+		break;
+	    case PJMEDIA_FORMAT_ILBC:
+		fmt_name = "ILBC";
+		break;
+	    case PJMEDIA_FORMAT_PCM:
+		fmt_name = "PCM";
+		break;
+	    default:
+		fmt_name = "Unknown";
+		break;
+	    }
+	    PJ_LOG(3, (THIS_FILE, "   - %s", fmt_name));
+	}
+    }
+
+    /* Create pool */
+    pool = pj_pool_create(&cp.factory, THIS_FILE, 512, 512, NULL);
+    if (pool == NULL) {
+    	app_perror("pj_pool_create()", status);
+        pj_caching_pool_destroy(&cp);
+    	pj_shutdown();
+    	return status;
+    }
+
+    /* Init delay buffer */
+    status = pjmedia_delay_buf_create(pool, THIS_FILE, CLOCK_RATE,
+				      SAMPLES_PER_FRAME, CHANNEL_COUNT,
+				      0, 0, &delaybuf);
+    if (status != PJ_SUCCESS) {
+    	app_perror("pjmedia_delay_buf_create()", status);
+        //pj_caching_pool_destroy(&cp);
+    	//pj_shutdown();
+    	//return status;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/* Sound capture callback */
+static pj_status_t rec_cb(void *user_data,
+			  pjmedia_frame *frame)
+{
+    PJ_UNUSED_ARG(user_data);
+
+    if (param.ext_fmt.id == PJMEDIA_FORMAT_PCM) {
+	pjmedia_delay_buf_put(delaybuf, (pj_int16_t*)frame->buf);
+    
+	if (frame->size != SAMPLES_PER_FRAME*2) {
+		    PJ_LOG(3, (THIS_FILE, "Size captured = %u",
+			       frame->size));
+	}
+    } else {
+	pjmedia_frame_ext *f_src = (pjmedia_frame_ext*)frame;
+	pjmedia_frame_ext *f_dst = (pjmedia_frame_ext*)frame_buf;
+	
+	copy_frame_ext(f_dst, f_src);
+    }
+
+    ++rec_cnt;
+    return PJ_SUCCESS;
+}
+
+/* Play cb */
+static pj_status_t play_cb(void *user_data,
+			   pjmedia_frame *frame)
+{
+    PJ_UNUSED_ARG(user_data);
+
+    if (param.ext_fmt.id == PJMEDIA_FORMAT_PCM) {
+	pjmedia_delay_buf_get(delaybuf, (pj_int16_t*)frame->buf);
+	frame->size = SAMPLES_PER_FRAME*2;
+	frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
+    } else {
+	pjmedia_frame_ext *f_src = (pjmedia_frame_ext*)frame_buf;
+	pjmedia_frame_ext *f_dst = (pjmedia_frame_ext*)frame;
+
+	copy_frame_ext(f_dst, f_src);
+    }
+
+    ++play_cnt;
+    return PJ_SUCCESS;
+}
+
+/* Start sound */
+static pj_status_t snd_start(unsigned flag)
+{
+    pj_status_t status;
+
+    if (strm != NULL) {
+    	app_perror("snd already open", PJ_EINVALIDOP);
+    	return PJ_EINVALIDOP;
+    }
+
+    pjmedia_aud_dev_default_param(0, &param);
+    param.channel_count = CHANNEL_COUNT;
+    param.clock_rate = CLOCK_RATE;
+    param.samples_per_frame = SAMPLES_PER_FRAME;
+    param.dir = (pjmedia_dir) flag;
+    param.ext_fmt.id = PJMEDIA_FORMAT_AMR;
+    param.ext_fmt.bitrate = 12200;
+    param.output_route = PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;
+
+    status = pjmedia_aud_stream_create(&param, &rec_cb, &play_cb, NULL, &strm);
+    if (status != PJ_SUCCESS) {
+    	app_perror("snd open", status);
+    	return status;
+    }
+
+    rec_cnt = play_cnt = 0;
+    pj_gettimeofday(&t_start);
+
+    pjmedia_delay_buf_reset(delaybuf);
+
+    status = pjmedia_aud_stream_start(strm);
+    if (status != PJ_SUCCESS) {
+    	app_perror("snd start", status);
+    	pjmedia_aud_stream_destroy(strm);
+    	strm = NULL;
+    	return status;
+    }
+
+    return PJ_SUCCESS;
+}
+
+/* Stop sound */
+static pj_status_t snd_stop()
+{
+    pj_time_val now;
+    pj_status_t status;
+
+    if (strm == NULL) {
+    	app_perror("snd not open", PJ_EINVALIDOP);
+    	return PJ_EINVALIDOP;
+    }
+
+    status = pjmedia_aud_stream_stop(strm);
+    if (status != PJ_SUCCESS) {
+    	app_perror("snd failed to stop", status);
+    }
+    status = pjmedia_aud_stream_destroy(strm);
+    strm = NULL;
+
+    pj_gettimeofday(&now);
+    PJ_TIME_VAL_SUB(now, t_start);
+
+    PJ_LOG(3,(THIS_FILE, "Duration: %d.%03d", now.sec, now.msec));
+    PJ_LOG(3,(THIS_FILE, "Captured: %d", rec_cnt));
+    PJ_LOG(3,(THIS_FILE, "Played: %d", play_cnt));
+
+    return status;
+}
+
+/* Shutdown application */
+static void app_fini()
+{
+    if (strm)
+    	snd_stop();
+
+    pjmedia_aud_subsys_shutdown();
+    pjmedia_delay_buf_destroy(delaybuf);
+    pj_pool_release(pool);
+    pj_caching_pool_destroy(&cp);
+    pj_shutdown();
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+/*
+ * The interractive console UI
+ */
+#include <e32base.h>
+
+class ConsoleUI : public CActive
+{
+public:
+    ConsoleUI(CConsoleBase *con);
+
+    // Run console UI
+    void Run();
+
+    // Stop
+    void Stop();
+
+protected:
+    // Cancel asynchronous read.
+    void DoCancel();
+
+    // Implementation: called when read has completed.
+    void RunL();
+
+private:
+    CConsoleBase *con_;
+};
+
+
+ConsoleUI::ConsoleUI(CConsoleBase *con)
+: CActive(EPriorityUserInput), con_(con)
+{
+    CActiveScheduler::Add(this);
+}
+
+// Run console UI
+void ConsoleUI::Run()
+{
+    con_->Read(iStatus);
+    SetActive();
+}
+
+// Stop console UI
+void ConsoleUI::Stop()
+{
+    DoCancel();
+}
+
+// Cancel asynchronous read.
+void ConsoleUI::DoCancel()
+{
+    con_->ReadCancel();
+}
+
+static void PrintMenu()
+{
+    PJ_LOG(3, (THIS_FILE, "\n\n"
+	    "Menu:\n"
+	    "  a    Start bidir sound\n"
+	    "  t    Start recorder\n"
+	    "  p    Start player\n"
+	    "  d    Stop & close sound\n"
+	    "  w    Quit\n"));
+}
+
+// Implementation: called when read has completed.
+void ConsoleUI::RunL()
+{
+    TKeyCode kc = con_->KeyCode();
+    pj_bool_t reschedule = PJ_TRUE;
+
+    switch (kc) {
+    case 'w':
+	    snd_stop();
+	    CActiveScheduler::Stop();
+	    reschedule = PJ_FALSE;
+	    break;
+    case 'a':
+    	snd_start(PJMEDIA_DIR_CAPTURE_PLAYBACK);
+	break;
+    case 't':
+    	snd_start(PJMEDIA_DIR_CAPTURE);
+	break;
+    case 'p':
+    	snd_start(PJMEDIA_DIR_PLAYBACK);
+    break;
+    case 'd':
+    	snd_stop();
+	break;
+    default:
+	    PJ_LOG(3,(THIS_FILE, "Keycode '%c' (%d) is pressed",
+		      kc, kc));
+	    break;
+    }
+
+    PrintMenu();
+
+    if (reschedule)
+	Run();
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+int app_main()
+{
+    if (app_init() != PJ_SUCCESS)
+        return -1;
+
+    // Run the UI
+    ConsoleUI *con = new ConsoleUI(console);
+
+    con->Run();
+
+    PrintMenu();
+    CActiveScheduler::Start();
+
+    delete con;
+
+    app_fini();
+    return 0;
+}
+