Index: pjproject/trunk/pjmedia/include/pjmedia/clock.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia/clock.h	(revision 2074)
+++ pjproject/trunk/pjmedia/include/pjmedia/clock.h	(revision 2075)
@@ -122,7 +122,8 @@
  * @param pool		    Pool to allocate memory.
  * @param clock_rate	    Number of samples per second.
+ * @param channel_count	    Number of channel.
  * @param samples_per_frame Number of samples per frame. This argument
- *			    along with clock_rate, specifies the interval
- *			    of each clock run (or clock ticks).
+ *			    along with clock_rate and channel_count, specifies 
+ *			    the interval of each clock run (or clock ticks).
  * @param options	    Bitmask of pjmedia_clock_options.
  * @param cb		    Callback to be called for each clock tick.
@@ -135,4 +136,5 @@
 PJ_DECL(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,
 					   unsigned clock_rate,
+					   unsigned channel_count,
 					   unsigned samples_per_frame,
 					   unsigned options,
Index: pjproject/trunk/pjmedia/src/pjmedia/clock_thread.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/clock_thread.c	(revision 2074)
+++ pjproject/trunk/pjmedia/src/pjmedia/clock_thread.c	(revision 2075)
@@ -56,4 +56,5 @@
 PJ_DEF(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,
 					  unsigned clock_rate,
+					  unsigned channel_count,
 					  unsigned samples_per_frame,
 					  unsigned options,
@@ -75,5 +76,6 @@
 	return status;
 
-    clock->interval.u64 = samples_per_frame * clock->freq.u64 / clock_rate;
+    clock->interval.u64 = samples_per_frame * clock->freq.u64 / 
+			  channel_count / clock_rate;
     clock->next_tick.u64 = 0;
     clock->timestamp.u64 = 0;
Index: pjproject/trunk/pjmedia/src/pjmedia/master_port.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/master_port.c	(revision 2074)
+++ pjproject/trunk/pjmedia/src/pjmedia/master_port.c	(revision 2075)
@@ -53,4 +53,5 @@
     pjmedia_master_port *m;
     unsigned clock_rate;
+    unsigned channel_count;
     unsigned samples_per_frame;
     unsigned bytes_per_frame;
@@ -65,8 +66,12 @@
 		     PJMEDIA_ENCCLOCKRATE);
 
-    /* Both ports MUST have equal ptime */
-    PJ_ASSERT_RETURN(u_port->info.clock_rate/u_port->info.samples_per_frame==
-		     d_port->info.clock_rate/d_port->info.samples_per_frame,
+    /* Both ports MUST have equal samples per frame */
+    PJ_ASSERT_RETURN(u_port->info.samples_per_frame==
+		     d_port->info.samples_per_frame,
 		     PJMEDIA_ENCSAMPLESPFRAME);
+
+    /* Both ports MUST have equal channel count */
+    PJ_ASSERT_RETURN(u_port->info.channel_count == d_port->info.channel_count,
+		     PJMEDIA_ENCCHANNEL);
 
 
@@ -74,4 +79,5 @@
     clock_rate = u_port->info.clock_rate;
     samples_per_frame = u_port->info.samples_per_frame;
+    channel_count = u_port->info.channel_count;
 
 
@@ -103,6 +109,7 @@
 
     /* Create media clock */
-    status = pjmedia_clock_create(pool, clock_rate, samples_per_frame, 
-				  options, &clock_callback, m, &m->clock);
+    status = pjmedia_clock_create(pool, clock_rate, channel_count, 
+				  samples_per_frame, options, &clock_callback,
+				  m, &m->clock);
     if (status != PJ_SUCCESS) {
 	pj_lock_destroy(m->lock);
Index: pjproject/trunk/pjsip-apps/src/test-pjsua/mod_pesq.py
===================================================================
--- pjproject/trunk/pjsip-apps/src/test-pjsua/mod_pesq.py	(revision 2074)
+++ pjproject/trunk/pjsip-apps/src/test-pjsua/mod_pesq.py	(revision 2075)
@@ -50,10 +50,33 @@
 	user_data.output_filename = re.compile(const.MEDIA_REC_FILE).search(ua2.inst_param.arg).group(1)
 
-	# Find appropriate clock rate for the input file
+	# Get WAV input length, in seconds
+	fin = wave.open(user_data.input_filename, "r")
+	if fin == None:
+		raise TestError("Failed opening input WAV file")
+	inwavlen = fin.getnframes() * 1.0 / fin.getframerate()
+	inwavlen += 0.2
+	fin.close()
+	print "WAV input len = " + str(inwavlen) + "s"
+
+	# Get clock rate of the output
 	mo_clock_rate = re.compile("\.(\d+)\.wav").search(user_data.output_filename)
 	if (mo_clock_rate==None):
 		raise TestError("Cannot compare input & output, incorrect output filename format")
 	clock_rate = mo_clock_rate.group(1)
-	user_data.input_filename = re.sub("\.\d+\.wav", "."+clock_rate+".wav", user_data.input_filename)
+	
+	# Get channel count of the output
+	channel_count = 1
+	if re.search("--stereo", ua2.inst_param.arg) != None:
+		channel_count = 2
+	
+	# Get matched input file from output file
+	# (PESQ evaluates only files whose same clock rate & channel count)
+	if channel_count == 2:
+	    if re.search("\.\d+\.\d+\.wav", user_data.input_filename) != None:
+		    user_data.input_filename = re.sub("\.\d+\.\d+\.wav", 
+						      "." + str(channel_count) + "."+clock_rate+".wav", user_data.input_filename)
+	    else:
+		    user_data.input_filename = re.sub("\.\d+\.wav", 
+						      "." + str(channel_count) + "."+clock_rate+".wav", user_data.input_filename)
 
 	if (clock_rate != "8") & (clock_rate != "16"):
@@ -62,13 +85,4 @@
 	# Get conference clock rate of UA2 for PESQ sample rate option
 	user_data.pesq_sample_rate_opt = "+" + clock_rate + "000"
-
-	# Get WAV input length, in seconds
-	fin = wave.open(user_data.input_filename, "r")
-	if fin == None:
-		raise TestError("Failed opening input WAV file")
-	inwavlen = fin.getnframes() // fin.getframerate()
-	if (fin.getnframes() % fin.getframerate()) > 0:
-		inwavlen = inwavlen + 1
-	fin.close()
 
 	# UA1 making call
@@ -110,5 +124,5 @@
 
 	# Parse ouput
-	mo_pesq_out = re.compile("Prediction[^=]+=\s+([\d\.]+)\s*").search(pesq_out[0])
+	mo_pesq_out = re.compile("Prediction[^=]+=\s+([\-\d\.]+)\s*").search(pesq_out[0])
 	if (mo_pesq_out == None):
 		raise TestError("Failed to fetch PESQ result")
Index: pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000.py
===================================================================
--- pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000.py	(revision 2075)
+++ pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000.py	(revision 2075)
@@ -0,0 +1,19 @@
+# $Id$
+#
+from inc_cfg import *
+
+ADD_PARAM = ""
+
+if (HAS_SND_DEV == 0):
+	ADD_PARAM += "--null-audio"
+
+# Call with L16/16000/1 codec
+test_param = TestParam(
+		"PESQ codec L16/16000/1",
+		[
+			InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --add-codec L16/16000/1 --clock-rate 16000 --play-file wavs/input.16.wav"),
+			InstanceParam("UA2", "--null-audio --max-calls=1 --add-codec L16/16000/1 --clock-rate 16000 --rec-file  wavs/tmp.16.wav --auto-answer 200")
+		]
+		)
+
+pesq_threshold = 3.5
Index: pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000_stereo.py
===================================================================
--- pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000_stereo.py	(revision 2075)
+++ pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000_stereo.py	(revision 2075)
@@ -0,0 +1,19 @@
+# $Id$
+#
+from inc_cfg import *
+
+ADD_PARAM = ""
+
+if (HAS_SND_DEV == 0):
+	ADD_PARAM += "--null-audio"
+
+# Call with L16/16000/2 codec
+test_param = TestParam(
+		"PESQ defaults pjsua settings",
+		[
+			InstanceParam("UA1", ADD_PARAM + " --stereo --max-calls=1 --clock-rate 16000 --add-codec L16/16000/2 --play-file wavs/input.2.16.wav"),
+			InstanceParam("UA2", "--null-audio --stereo --max-calls=1 --clock-rate 16000 --add-codec L16/16000/2 --rec-file  wavs/tmp.2.16.wav   --auto-answer 200")
+		]
+		)
+
+pesq_threshold = None
Index: pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000.py
===================================================================
--- pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000.py	(revision 2075)
+++ pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000.py	(revision 2075)
@@ -0,0 +1,19 @@
+# $Id$
+#
+from inc_cfg import *
+
+ADD_PARAM = ""
+
+if (HAS_SND_DEV == 0):
+	ADD_PARAM += "--null-audio"
+
+# Call with L16/8000/1 codec
+test_param = TestParam(
+		"PESQ codec L16/8000/1",
+		[
+			InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --add-codec L16/8000/1 --clock-rate 8000 --play-file wavs/input.8.wav"),
+			InstanceParam("UA2", "--null-audio --max-calls=1 --add-codec L16/8000/1 --clock-rate 8000 --rec-file  wavs/tmp.8.wav --auto-answer 200")
+		]
+		)
+
+pesq_threshold = 3.5
Index: pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000_stereo.py
===================================================================
--- pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000_stereo.py	(revision 2075)
+++ pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000_stereo.py	(revision 2075)
@@ -0,0 +1,19 @@
+# $Id$
+#
+from inc_cfg import *
+
+ADD_PARAM = ""
+
+if (HAS_SND_DEV == 0):
+	ADD_PARAM += "--null-audio"
+
+# Call with L16/8000/2 codec
+test_param = TestParam(
+		"PESQ defaults pjsua settings",
+		[
+			InstanceParam("UA1", ADD_PARAM + " --stereo --max-calls=1 --clock-rate 8000 --add-codec L16/8000/2 --play-file wavs/input.2.8.wav"),
+			InstanceParam("UA2", "--null-audio --stereo --max-calls=1 --clock-rate 8000 --add-codec L16/8000/2 --rec-file  wavs/tmp.2.8.wav   --auto-answer 200")
+		]
+		)
+
+pesq_threshold = None
Index: pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000.py
===================================================================
--- pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000.py	(revision 2075)
+++ pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000.py	(revision 2075)
@@ -0,0 +1,17 @@
+# $Id$
+#
+from inc_cfg import *
+
+# Call with L16/16000/1 codec
+test_param = TestParam(
+		"PESQ codec L16/16000/1 (RX side uses snd dev)",
+		[
+			InstanceParam("UA1", "--max-calls=1 --add-codec L16/16000/1 --clock-rate 16000 --play-file wavs/input.16.wav --null-audio"),
+			InstanceParam("UA2", "--max-calls=1 --add-codec L16/16000/1 --clock-rate 16000 --rec-file  wavs/tmp.16.wav   --auto-answer 200")
+		]
+		)
+
+if (HAS_SND_DEV == 0):
+	test_param.skip = True
+
+pesq_threshold = 3.5
Index: pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000_stereo.py
===================================================================
--- pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000_stereo.py	(revision 2075)
+++ pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000_stereo.py	(revision 2075)
@@ -0,0 +1,17 @@
+# $Id$
+#
+from inc_cfg import *
+
+# Call with L16/16000/2 codec
+test_param = TestParam(
+		"PESQ defaults pjsua settings",
+		[
+			InstanceParam("UA1", "--stereo --max-calls=1 --clock-rate 16000 --add-codec L16/16000/2 --play-file wavs/input.2.16.wav --null-audio"),
+			InstanceParam("UA2", "--stereo --max-calls=1 --clock-rate 16000 --add-codec L16/16000/2 --rec-file  wavs/tmp.2.16.wav   --auto-answer 200")
+		]
+		)
+
+if (HAS_SND_DEV == 0):
+	test_param.skip = True
+	
+pesq_threshold = None
Index: pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000.py
===================================================================
--- pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000.py	(revision 2075)
+++ pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000.py	(revision 2075)
@@ -0,0 +1,17 @@
+# $Id$
+#
+from inc_cfg import *
+
+# Call with L16/8000/1 codec
+test_param = TestParam(
+		"PESQ codec L16/8000/1 (RX side uses snd dev)",
+		[
+			InstanceParam("UA1", "--max-calls=1 --add-codec L16/8000/1 --clock-rate 8000 --play-file wavs/input.8.wav --null-audio"),
+			InstanceParam("UA2", "--max-calls=1 --add-codec L16/8000/1 --clock-rate 8000 --rec-file  wavs/tmp.8.wav   --auto-answer 200")
+		]
+		)
+
+if (HAS_SND_DEV == 0):
+	test_param.skip = True
+
+pesq_threshold = 3.5
Index: pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000_stereo.py
===================================================================
--- pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000_stereo.py	(revision 2075)
+++ pjproject/trunk/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000_stereo.py	(revision 2075)
@@ -0,0 +1,17 @@
+# $Id$
+#
+from inc_cfg import *
+
+# Call with L16/8000/2 codec
+test_param = TestParam(
+		"PESQ defaults pjsua settings",
+		[
+			InstanceParam("UA1", "--stereo --max-calls=1 --clock-rate 8000 --add-codec L16/8000/2 --play-file wavs/input.2.8.wav --null-audio"),
+			InstanceParam("UA2", "--stereo --max-calls=1 --clock-rate 8000 --add-codec L16/8000/2 --rec-file  wavs/tmp.2.8.wav   --auto-answer 200")
+		]
+		)
+
+if (HAS_SND_DEV == 0):
+	test_param.skip = True
+	
+pesq_threshold = None
