Added new callback for module: post_func (called at the end of the test), added userdata param for modules, and added new module media_playrec with some scripts

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@2029 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip-apps/src/test-pjsua/inc_cfg.py b/pjsip-apps/src/test-pjsua/inc_cfg.py
index 531fd1c..d8519c3 100644
--- a/pjsip-apps/src/test-pjsua/inc_cfg.py
+++ b/pjsip-apps/src/test-pjsua/inc_cfg.py
@@ -1,4 +1,4 @@
-# $Id:$
+# $Id$
 import random
 
 DEFAULT_ECHO = True
@@ -71,13 +71,19 @@
 	process = []
 	# the function for test body
 	test_func = None
+	post_func = None
+	user_data = None
 	def __init__(	self, 
 			title, 		# Test title
 			inst_params, 	# InstanceParam's as list
-			func=None):
+			func=None,
+			post_func=None,
+			user_data=None):
 		self.title = title
 		self.inst_params = inst_params
 		self.test_func = func
+		self.post_func = post_func
+		self.user_data = user_data
 
 
 
diff --git a/pjsip-apps/src/test-pjsua/inc_const.py b/pjsip-apps/src/test-pjsua/inc_const.py
index 37c7e96..dd8d1b1 100644
--- a/pjsip-apps/src/test-pjsua/inc_const.py
+++ b/pjsip-apps/src/test-pjsua/inc_const.py
@@ -1,4 +1,4 @@
-# $Id:$
+# $Id$
 # Useful constants
 
 
@@ -34,6 +34,18 @@
 RX_DTMF = "Incoming DTMF on call [0-9]+: "
 
 ##########################
+# MEDIA
+#
+
+# Connecting/disconnecting ports
+MEDIA_CONN_PORT_SUCCESS = "Port \d+ \(.+\) transmitting to port"
+MEDIA_DISCONN_PORT_SUCCESS = "Port \d+ \(.+\) stop transmitting to port"
+
+# Filename to play / record
+MEDIA_PLAY_FILE = "--play-file (\S+)"
+MEDIA_REC_FILE = "--rec-file (\S+)"
+
+##########################
 # MISC
 #
 
diff --git a/pjsip-apps/src/test-pjsua/mod_call.py b/pjsip-apps/src/test-pjsua/mod_call.py
index ff41593..0302341 100644
--- a/pjsip-apps/src/test-pjsua/mod_call.py
+++ b/pjsip-apps/src/test-pjsua/mod_call.py
@@ -1,4 +1,4 @@
-# $Id:$
+# $Id$
 import time
 import imp
 import sys
@@ -9,7 +9,7 @@
 
 
 # Test body function
-def test_func(t):
+def test_func(t, user_data):
 	callee = t.process[0]
 	caller = t.process[1]
 
diff --git a/pjsip-apps/src/test-pjsua/mod_media_playrec.py b/pjsip-apps/src/test-pjsua/mod_media_playrec.py
new file mode 100644
index 0000000..8d8a60f
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/mod_media_playrec.py
@@ -0,0 +1,86 @@
+# $Id$
+
+# PLAYFILE -> RECFILE:
+# input file is played and is recorded to output, then compare them.
+#	null-audio
+#	port 1: wav file input xxxxxx.clock_rate.wav, e.g: test1.8.wav
+#	port 2: wav file ouput xxxxxx.clock_rate.wav, e.g: res1.8.wav
+#	wav input more than 3 seconds
+
+import time
+import imp
+import sys
+import re
+import subprocess
+import inc_const as const
+
+# Load configuration
+cfg_file = imp.load_source("cfg_file", sys.argv[2])
+
+# WAV similarity calculator
+COMPARE_WAV_EXE = "tools/cmp_wav.exe"
+
+# UserData
+class mod_media_playrec_user_data:
+	input_filename = ""
+	output_filename = ""
+
+# Test body function
+def test_func(t, ud):
+	endpt = t.process[0]
+	
+	# Get input file name
+	endpt.sync_stdout()
+	endpt.send("dc")
+	line = endpt.expect(const.MEDIA_PLAY_FILE)
+	ud.input_filename = re.compile(const.MEDIA_PLAY_FILE).match(line).group(1)
+	endpt.trace("Input file = " + ud.input_filename)
+
+	# Get output file name
+	endpt.sync_stdout()
+	endpt.send("dc")
+	line = endpt.expect(const.MEDIA_REC_FILE)
+	ud.output_filename = re.compile(const.MEDIA_REC_FILE).match(line).group(1)
+	endpt.trace("Output file = " + ud.output_filename)
+
+	# Find appropriate clock rate for the input file
+	clock_rate = re.compile(".+(\.\d+\.wav)$").match(ud.output_filename).group(1)
+	if (clock_rate==None):
+		endpt.trace("Cannot compare input & output, incorrect output filename format")
+		return
+	ud.input_filename = re.sub("\.\d+\.wav$", clock_rate, ud.input_filename)
+	endpt.trace("WAV file to be compared with output = " + ud.input_filename)
+
+	# Connect input-output file
+	endpt.sync_stdout()
+
+	endpt.send("cc 1 2")
+	endpt.expect(const.MEDIA_CONN_PORT_SUCCESS)
+
+	# Wait
+	time.sleep(3)
+
+	endpt.sync_stdout()
+
+	# Disconnect input-output file
+	endpt.send("cd 1 2")
+	endpt.expect(const.MEDIA_DISCONN_PORT_SUCCESS)
+
+
+# Post body function
+def post_func(t, ud):
+	endpt = t.process[0]
+
+	# Check WAV similarity
+	fullcmd = COMPARE_WAV_EXE + " " + ud.input_filename + " " + ud.output_filename + " " + "3000"
+	endpt.trace("Popen " + fullcmd)
+	cmp_proc = subprocess.Popen(fullcmd, stdout=subprocess.PIPE, universal_newlines=True)
+	line = cmp_proc.stdout.readline()
+	endpt.trace("WAV similarity = " + line)
+
+
+# Here where it all comes together
+test = cfg_file.test_param
+test.test_func = test_func
+test.post_func = post_func
+test.user_data = mod_media_playrec_user_data()
diff --git a/pjsip-apps/src/test-pjsua/mod_pres.py b/pjsip-apps/src/test-pjsua/mod_pres.py
index e3b996a..6b6fb2b 100644
--- a/pjsip-apps/src/test-pjsua/mod_pres.py
+++ b/pjsip-apps/src/test-pjsua/mod_pres.py
@@ -1,4 +1,4 @@
-# $Id:$
+# $Id$
 import time
 import imp
 import sys
@@ -9,7 +9,7 @@
 
 
 # Test body function
-def test_func(t):
+def test_func(t, user_data):
 	u1 = t.process[0]
 	uri1 = cfg_file.test_param.inst_params[0].uri
 	acc1 = "-1"
diff --git a/pjsip-apps/src/test-pjsua/run.py b/pjsip-apps/src/test-pjsua/run.py
index 0b374de..34792da 100644
--- a/pjsip-apps/src/test-pjsua/run.py
+++ b/pjsip-apps/src/test-pjsua/run.py
@@ -178,7 +178,7 @@
 # Run the test function
 if script.test.test_func != None:
 	try:
-		script.test.test_func(script.test)
+		script.test.test_func(script.test, script.test.user_data)
 	except TestError, e:
 		handle_error(e.desc, script.test)
 
@@ -196,6 +196,13 @@
 	p.expect(const.DESTROYED, False)
 	p.wait()
 
+# Run the post test function
+if script.test.post_func != None:
+	try:
+		script.test.post_func(script.test, script.test.user_data)
+	except TestError, e:
+		handle_error(e.desc, script.test)
+
 # Done
 print "Test " + script.test.title + " completed successfully"
 sys.exit(0)
diff --git a/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_16.py b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_16.py
new file mode 100644
index 0000000..484fe6d
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_16.py
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+# simple test
+test_param = TestParam(
+		"Resample (large filter) 11 KHZ to 16 KHZ",
+		[
+			InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 16000 --play-file wavs/input.11.wav --rec-file wavs/tmp_output.16.wav")
+		]
+		)
diff --git a/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_22.py b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_22.py
new file mode 100644
index 0000000..71f71dc
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_22.py
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+# simple test
+test_param = TestParam(
+		"Resample (large filter) 11 KHZ to 22 KHZ",
+		[
+			InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 22050 --play-file wavs/input.11.wav --rec-file wavs/tmp_output.22.wav")
+		]
+		)
diff --git a/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_32.py b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_32.py
new file mode 100644
index 0000000..8f9ca47
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_32.py
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+# simple test
+test_param = TestParam(
+		"Resample (large filter) 11 KHZ to 32 KHZ",
+		[
+			InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 32000 --play-file wavs/input.11.wav --rec-file wavs/tmp_output.32.wav")
+		]
+		)
diff --git a/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_44.py b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_44.py
new file mode 100644
index 0000000..42bba80
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_44.py
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+# simple test
+test_param = TestParam(
+		"Resample (large filter) 11 KHZ to 44 KHZ",
+		[
+			InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 44100 --play-file wavs/input.11.wav --rec-file wavs/tmp_output.44.wav")
+		]
+		)
diff --git a/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_48.py b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_48.py
new file mode 100644
index 0000000..f4b996b
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_48.py
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+# simple test
+test_param = TestParam(
+		"Resample (large filter) 11 KHZ to 48 KHZ",
+		[
+			InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 48000 --play-file wavs/input.11.wav --rec-file wavs/tmp_output.48.wav")
+		]
+		)
diff --git a/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_8.py b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_8.py
new file mode 100644
index 0000000..e502fc4
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_11_8.py
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+# simple test
+test_param = TestParam(
+		"Resample (large filter) 11 KHZ to 8 KHZ",
+		[
+			InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 8000 --play-file wavs/input.11.wav --rec-file wavs/tmp_output.8.wav")
+		]
+		)
diff --git a/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_11.py b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_11.py
new file mode 100644
index 0000000..8abd534
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_11.py
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+# simple test
+test_param = TestParam(
+		"Resample (large filter) 8 KHZ to 11 KHZ",
+		[
+			InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 11025 --play-file wavs/input.8.wav --rec-file wavs/tmp_output.11.wav")
+		]
+		)
diff --git a/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_16.py b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_16.py
new file mode 100644
index 0000000..4b19b23
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_16.py
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+# simple test
+test_param = TestParam(
+		"Resample (large filter) 8 KHZ to 16 KHZ",
+		[
+			InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 16000 --play-file wavs/input.8.wav --rec-file wavs/tmp_output.16.wav")
+		]
+		)
diff --git a/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_22.py b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_22.py
new file mode 100644
index 0000000..092b639
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_22.py
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+# simple test
+test_param = TestParam(
+		"Resample (large filter) 8 KHZ to 22 KHZ",
+		[
+			InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 22050 --play-file wavs/input.8.wav --rec-file wavs/tmp_output.22.wav")
+		]
+		)
diff --git a/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_32.py b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_32.py
new file mode 100644
index 0000000..a3c9133
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_32.py
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+# simple test
+test_param = TestParam(
+		"Resample (large filter) 8 KHZ to 32 KHZ",
+		[
+			InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 32000 --play-file wavs/input.8.wav --rec-file wavs/tmp_output.32.wav")
+		]
+		)
diff --git a/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_44.py b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_44.py
new file mode 100644
index 0000000..90f99df
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_44.py
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+# simple test
+test_param = TestParam(
+		"Resample (large filter) 8 KHZ to 44 KHZ",
+		[
+			InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 44100 --play-file wavs/input.8.wav --rec-file wavs/tmp_output.44.wav")
+		]
+		)
diff --git a/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_48.py b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_48.py
new file mode 100644
index 0000000..bdb82a3
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/scripts-media-playrec/100_resample_lf_8_48.py
@@ -0,0 +1,11 @@
+# $Id$
+#
+from inc_cfg import *
+
+# simple test
+test_param = TestParam(
+		"Resample (large filter) 8 KHZ to 48 KHZ",
+		[
+			InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 48000 --play-file wavs/input.8.wav --rec-file wavs/tmp_output.48.wav")
+		]
+		)
diff --git a/pjsip-apps/src/test-pjsua/tools/cmp_wav.c b/pjsip-apps/src/test-pjsua/tools/cmp_wav.c
new file mode 100644
index 0000000..398a721
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/tools/cmp_wav.c
@@ -0,0 +1,245 @@
+/* $Id$ */
+
+#include <pjmedia.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define app_perror(a,b,c) printf("%s: %s (%d)", a, b, c)
+
+
+/* For logging purpose. */
+#define THIS_FILE   "cmp_wav.c"
+#define BYTES_PER_FRAME	    512
+
+static const char *desc = 
+" FILE		    						    \n"
+"		    						    \n"
+"  cmp_wav.c	    						    \n"
+"		    						    \n"
+" PURPOSE	    						    \n"
+"		    						    \n"
+"  Compare two WAV files.					    \n"
+"		    						    \n"
+" USAGE		    						    \n"
+"		    						    \n"
+"  cmp_wav ORIGINAL_WAV DEGRADED_WAV [TIME] [DETAIL]		    \n"
+"		    						    \n"
+"  ORIGINAL_WAV	    The original WAV file as reference.		    \n"
+"  DEGRADED_WAV	    The degraded WAV file.			    \n"
+"  TIME	            Compare only some part of the files		    \n"
+"                   (in ms, since the beginning).		    \n"
+"                   Specify 0 (default) to compare the whole time.  \n"
+"  DETAIL           Show detail result, 1 or 0 (default=0, means no)\n"
+"		    						    \n"
+"  Both files must have same clock rate and must contain	    \n"
+"  uncompressed (i.e. 16bit) PCM.				    \n";
+
+
+/* Sum of multiplication of corresponding samples in buf1 & buf2 */
+double sum_mult_sig(pj_int16_t *buf1, pj_int16_t *buf2, unsigned nsamples)
+{
+    double mag = 0;
+
+    while (nsamples--)
+	mag += (double)*buf1++ * (double)*buf2++;
+
+    return mag;
+}
+
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+    pj_caching_pool cp;
+    pjmedia_endpt *med_endpt;
+    pj_pool_t *pool;
+    pjmedia_port *file_ori_port;
+    pjmedia_port *file_deg_port;
+    pj_status_t status;
+    unsigned first_nsamples = 0;
+    unsigned samples_compared = 0;
+
+    char buf1[BYTES_PER_FRAME];
+    char buf2[BYTES_PER_FRAME];
+
+    double ref_mag = 0;
+    double deg_mag = 0;
+    double mix_mag = 0;
+
+    int detail = 0;
+    int res_deg, res_mix, res_overall;
+
+    if (argc < 3) {
+    	puts("Error: original & degraded filename required");
+	puts(desc);
+	return 1;
+    }
+
+    /* Set log level. */
+    pj_log_set_level(3);
+
+    /* Must init PJLIB first: */
+    status = pj_init();
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Must create a pool factory before we can allocate any memory. */
+    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+    /* 
+     * Initialize media endpoint.
+     * This will implicitly initialize PJMEDIA too.
+     */
+    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Create memory pool for our file player */
+    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
+			   "wav",	    /* pool name.	    */
+			   4000,	    /* init size	    */
+			   4000,	    /* increment size	    */
+			   NULL		    /* callback on error    */
+			   );
+
+    /* Create file media port from the original WAV file */
+    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
+					      argv[1],	/* file to play	    */
+					      40,	/* ptime.	    */
+					      PJMEDIA_FILE_NO_LOOP,	/* flags	    */
+					      0,	/* default buffer   */
+					      &file_ori_port/* returned port    */
+					      );
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to use WAV file", status);
+	return 1;
+    }
+
+    /* Create file media port from the degraded WAV file */
+    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
+					      argv[2],	/* file to play	    */
+					      40,	/* ptime.	    */
+					      PJMEDIA_FILE_NO_LOOP,	/* flags	    */
+					      0,	/* default buffer   */
+					      &file_deg_port/* returned port    */
+					      );
+    if (status != PJ_SUCCESS) {
+	app_perror(THIS_FILE, "Unable to use WAV file", status);
+	return 1;
+    }
+
+    if (file_ori_port->info.clock_rate != file_deg_port->info.clock_rate) {
+	app_perror(THIS_FILE, "Clock rates must be same.", PJ_EINVAL);
+	return 1;
+    }
+
+    if (argc > 3)
+	first_nsamples = atoi(argv[3]) * file_ori_port->info.clock_rate / 1000;
+
+    if (argc > 4)
+	detail = atoi(argv[4]);
+
+    while (1) {
+	pjmedia_frame f1, f2;
+
+	f1.buf = buf1;
+	f1.size = BYTES_PER_FRAME;
+	f2.buf = buf2;
+	f2.size = BYTES_PER_FRAME;
+
+	status = pjmedia_port_get_frame(file_ori_port, &f1);
+	if (status == PJ_EEOF) {
+	    break;
+	} else if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Error occured while reading file", status);
+	    break;
+	}
+	status = pjmedia_port_get_frame(file_deg_port, &f2);
+	if (status == PJ_EEOF) {
+	    break;
+	} else if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Error occured while reading file", status);
+	    break;
+	}
+
+	/* Calculate magnitudes */
+	ref_mag += sum_mult_sig(f1.buf, f1.buf, BYTES_PER_FRAME >> 1);
+	deg_mag += sum_mult_sig(f2.buf, f2.buf, BYTES_PER_FRAME >> 1);
+	mix_mag += sum_mult_sig(f1.buf, f2.buf, BYTES_PER_FRAME >> 1);
+
+	samples_compared += BYTES_PER_FRAME >> 1;
+	if (first_nsamples && samples_compared >= first_nsamples)
+	    break;
+    }
+
+    /* Degraded magnitude compared to reference magnitude 
+     */
+    res_deg = (int) (deg_mag / ref_mag * 100.0);
+    if (res_deg < 0)
+	res_deg = -1;
+    else if (res_deg >= 81)
+	res_deg = 9;
+    else
+	res_deg = pj_isqrt(res_deg);
+
+    /* Mixed magnitude (don't know what this is actually :D) compared to 
+     * reference magnitude 
+     */
+    res_mix = (int) (mix_mag / ref_mag * 100.0);
+    if (res_mix < 0)
+	res_mix = -1;
+    else if (res_mix >= 81)
+	res_mix = 9;
+    else
+	res_mix = pj_isqrt(res_mix);
+
+    /* Overall score.
+     * If mixed score is -1, then overall score should be -1 as well.
+     * Apply no weighting (1:1) for now.
+     */
+    if (res_mix == -1)
+	res_overall = -1;
+    else
+	res_overall = (res_mix*1 + res_deg*1) / 2;
+
+    if (detail) {
+	printf("Reference = %.0f\n", ref_mag);
+	printf("Degraded  = %.0f\n", deg_mag);
+	printf("Mixed     = %.0f\n", mix_mag);
+
+	printf("\n");
+
+	printf("Score 1   = %d\n", res_deg);
+	printf("Score 2   = %d\n", res_mix);
+
+	printf("\n");
+    }
+
+    printf("Overall   = %d\n", res_overall);
+
+    /* Destroy file port */
+    status = pjmedia_port_destroy( file_ori_port );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    status = pjmedia_port_destroy( file_deg_port );
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+    /* Release application pool */
+    pj_pool_release( pool );
+
+    /* Destroy media endpoint. */
+    pjmedia_endpt_destroy( med_endpt );
+
+    /* Destroy pool factory */
+    pj_caching_pool_destroy( &cp );
+
+    /* Shutdown PJLIB */
+    pj_shutdown();
+
+
+    /* Done. */
+    return 0;
+}
+
diff --git a/pjsip-apps/src/test-pjsua/tools/cmp_wav.exe b/pjsip-apps/src/test-pjsua/tools/cmp_wav.exe
new file mode 100644
index 0000000..6220771
--- /dev/null
+++ b/pjsip-apps/src/test-pjsua/tools/cmp_wav.exe
Binary files differ