Index: /pjproject/trunk/pjmedia/src/pjmedia/echo_common.c
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia/echo_common.c	(revision 3114)
+++ /pjproject/trunk/pjmedia/src/pjmedia/echo_common.c	(revision 3115)
@@ -25,4 +25,5 @@
 #include <pj/list.h>
 #include <pj/log.h>
+#include <pj/math.h>
 #include <pj/pool.h>
 #include "echo_internal.h"
@@ -47,6 +48,4 @@
 
     pj_bool_t	     lat_ready;	    /* lat_buf has been filled in.	    */
-    unsigned	     lat_target_cnt;/* Target number of frames in lat_buf   */
-    unsigned	     lat_buf_cnt;   /* Actual number of frames in lat_buf   */
     struct frame     lat_buf;	    /* Frame queue for delayed playback	    */
     struct frame     lat_free;	    /* Free frame list.			    */
@@ -145,5 +144,5 @@
 					 pjmedia_echo_state **p_echo )
 {
-    unsigned ptime;
+    unsigned ptime, lat_cnt;
     pjmedia_echo_state *ec;
     pj_status_t status;
@@ -195,20 +194,19 @@
     /* Create latency buffers */
     ptime = samples_per_frame * 1000 / clock_rate;
-    if (latency_ms == 0) {
+    if (latency_ms > ptime) {
+	/* Normalize latency with delaybuf/WSOLA latency */
+	latency_ms -= PJ_MIN(ptime, PJMEDIA_WSOLA_DELAY_MSEC);
+    }
+    if (latency_ms < ptime) {
 	/* Give at least one frame delay to simplify programming */
 	latency_ms = ptime;
     }
-    ec->lat_target_cnt = latency_ms / ptime;
-    if (ec->lat_target_cnt != 0) {
-	unsigned i;
-	for (i=0; i < ec->lat_target_cnt; ++i)  {
-	    struct frame *frm;
-
-	    frm = (struct frame*) pj_pool_alloc(pool, (samples_per_frame<<1) +
-						      sizeof(struct frame));
-	    pj_list_push_back(&ec->lat_free, frm);
-	}
-    } else {
-	ec->lat_ready = PJ_TRUE;
+    lat_cnt = latency_ms / ptime;
+    while (lat_cnt--)  {
+	struct frame *frm;
+
+	frm = (struct frame*) pj_pool_alloc(pool, (samples_per_frame<<1) +
+						  sizeof(struct frame));
+	pj_list_push_back(&ec->lat_free, frm);
     }
 
Index: /pjproject/trunk/pjmedia/src/pjmedia/sound_port.c
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia/sound_port.c	(revision 3114)
+++ /pjproject/trunk/pjmedia/src/pjmedia/sound_port.c	(revision 3115)
@@ -564,5 +564,8 @@
 	    //delay_ms = (si.rec_latency + si.play_latency) * 1000 /
 	    //	   snd_port->clock_rate;
-	    delay_ms = prm.output_latency_ms;
+	    /* Set EC latency to 3/4 of output latency to reduce the
+	     * possibility of missing/late reference frame.
+	     */
+	    delay_ms = prm.output_latency_ms * 3/4;
 	    status = pjmedia_echo_create2(pool, snd_port->clock_rate, 
 					  snd_port->channel_count,
Index: /pjproject/trunk/pjsip-apps/src/samples/aectest.c
===================================================================
--- /pjproject/trunk/pjsip-apps/src/samples/aectest.c	(revision 3114)
+++ /pjproject/trunk/pjsip-apps/src/samples/aectest.c	(revision 3115)
@@ -56,9 +56,17 @@
 "\n"
 " options:\n"
-"  -d  The delay between playback and capture in ms. Default is zero.\n"
+"  -d  The delay between playback and capture in ms, at least 25 ms.\n"
+"      Default is 25 ms. See note below.                            \n"
 "  -l  Set the echo tail length in ms. Default is 200 ms	    \n"
 "  -r  Set repeat count (default=1)                                 \n"
 "  -a  Algorithm: 0=default, 1=speex, 3=echo suppress		    \n"
-"  -i  Interactive						    \n";
+"  -i  Interactive						    \n"
+"\n"
+" Note that for the AEC internal buffering mechanism, it is required\n"
+" that the echoed signal (in REC.WAV) is delayed from the           \n"
+" corresponding reference signal (in PLAY.WAV) at least as much as  \n"
+" frame time + PJMEDIA_WSOLA_DELAY_MSEC. In this application, frame \n"
+" time is 20 ms and default PJMEDIA_WSOLA_DELAY_MSEC is 5 ms, hence \n"
+" 25 ms delay is the minimum value.                                 \n";
 
 /* 
@@ -92,5 +100,5 @@
     pjmedia_frame play_frame, rec_frame;
     unsigned opt = 0;
-    unsigned latency_ms = 0;
+    unsigned latency_ms = 25;
     unsigned tail_ms = TAIL_LENGTH;
     pj_timestamp t0, t1;
@@ -102,4 +110,8 @@
 	case 'd':
 	    latency_ms = atoi(pj_optarg);
+	    if (latency_ms < 25) {
+		puts("Invalid delay");
+		puts(desc);
+	    }
 	    break;
 	case 'l':
@@ -128,5 +140,5 @@
 	    repeat = atoi(pj_optarg);
 	    if (repeat < 1) {
-		puts("Invalid algorithm");
+		puts("Invalid repeat count");
 		puts(desc);
 		return 1;
@@ -252,5 +264,5 @@
     pj_get_timestamp(&t1);
 
-    i = pjmedia_wav_writer_port_get_pos(wav_out) * 1000 / 
+    i = pjmedia_wav_writer_port_get_pos(wav_out) / sizeof(pj_int16_t) * 1000 / 
 	(wav_out->info.clock_rate * wav_out->info.channel_count);
     PJ_LOG(3,(THIS_FILE, "Processed %3d.%03ds audio",
