blob: 431b312ba28a04a9896b3cc01547fa5356f05aee [file] [log] [blame]
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +00001# $Id$
2
3# Quality test of media calls.
4# - UA1 calls UA2
5# - UA1 plays a file until finished to be streamed to UA2
6# - UA2 records from stream
7# - Apply PESQ to played file (reference) and recorded file (degraded)
8#
9# File should be:
10# - naming: xxxxxx.CLOCK_RATE.wav, e.g: test1.8.wav
11# - clock-rate of those files can only be 8khz or 16khz
12
13import time
14import imp
15import sys
16import re
17import subprocess
18import inc_const as const
19
20from inc_cfg import *
21
22# Load configuration
23cfg_file = imp.load_source("cfg_file", sys.argv[2])
24
25# PESQ configs
26# PESQ_THRESHOLD specifies the minimum acceptable PESQ MOS value, so test can be declared successful
27PESQ = "tools/pesq.exe"
Nanang Izzuddin6ee166d2008-06-26 12:26:52 +000028PESQ_THRESHOLD = 3.0
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +000029
30# UserData
31class mod_pesq_user_data:
32 # Sample rate option for PESQ
33 pesq_sample_rate_opt = ""
34 # Input/Reference filename
35 input_filename = ""
36 # Output/Degraded filename
37 output_filename = ""
38
39# Test body function
40def test_func(t, user_data):
Nanang Izzuddin6ee166d2008-06-26 12:26:52 +000041
42 if len(t.process) == 0:
43 return
44
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +000045 ua1 = t.process[0]
46 ua2 = t.process[1]
47
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +000048 # Get input file name
Nanang Izzuddinacb3e322008-06-25 18:18:32 +000049 user_data.input_filename = re.compile(const.MEDIA_PLAY_FILE).search(ua1.inst_param.arg).group(1)
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +000050
51 # Get output file name
Nanang Izzuddinacb3e322008-06-25 18:18:32 +000052 user_data.output_filename = re.compile(const.MEDIA_REC_FILE).search(ua2.inst_param.arg).group(1)
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +000053
54 # Find appropriate clock rate for the input file
Nanang Izzuddinacb3e322008-06-25 18:18:32 +000055 mo_clock_rate = re.compile("\.(\d+)\.wav").search(user_data.output_filename)
56 if (mo_clock_rate==None):
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +000057 raise TestError("Cannot compare input & output, incorrect output filename format")
Nanang Izzuddinacb3e322008-06-25 18:18:32 +000058 clock_rate = mo_clock_rate.group(1)
59 user_data.input_filename = re.sub("\.\d+\.wav", "."+clock_rate+".wav", user_data.input_filename)
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +000060
Nanang Izzuddinacb3e322008-06-25 18:18:32 +000061 if (clock_rate != "8") & (clock_rate != "16"):
62 raise TestError("PESQ only works on clock rate 8kHz or 16kHz, clock rate used = "+clock_rate+ "kHz")
63
64 # Get conference clock rate of UA2 for PESQ sample rate option
65 user_data.pesq_sample_rate_opt = "+" + clock_rate + "000"
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +000066
67 # UA1 making call
68 ua1.send("m")
69 ua1.send(t.inst_params[1].uri)
70 ua1.expect(const.STATE_CALLING)
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +000071 ua2.expect(const.STATE_CONFIRMED)
72
Nanang Izzuddinacb3e322008-06-25 18:18:32 +000073 # Disconnect mic -> rec file to avoid echo recorded when using sound device
74 ua2.send("cd 0 1")
75
76 # Auto answer, auto play, auto hangup
77 # Just wait for call disconnected
78 # Assumed WAV input is no more than 30 secs
79 while 1:
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +000080 line = ua2.proc.stdout.readline()
81 if line == "":
82 raise TestError(ua2.name + ": Premature EOF")
Nanang Izzuddinacb3e322008-06-25 18:18:32 +000083
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +000084 # Search for disconnected text
85 if re.search(const.STATE_DISCONNECTED, line) != None:
86 break
87
88
89# Post body function
90def post_func(t, user_data):
91 endpt = t.process[0]
92
93 # Execute PESQ
94 fullcmd = PESQ + " " + user_data.pesq_sample_rate_opt + " " + user_data.input_filename + " " + user_data.output_filename
95 endpt.trace("Popen " + fullcmd)
96 pesq_proc = subprocess.Popen(fullcmd, stdout=subprocess.PIPE, universal_newlines=True)
97 pesq_out = pesq_proc.communicate()
98
99 # Parse ouput
Nanang Izzuddin6ee166d2008-06-26 12:26:52 +0000100 mo_pesq_out = re.compile("Prediction[^=]+=\s+([\d\.]+)\s*").search(pesq_out[0])
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +0000101 if (mo_pesq_out == None):
102 raise TestError("Failed to fetch PESQ result")
103
104 # Evaluate the similarity value
105 pesq_res = mo_pesq_out.group(1)
Nanang Izzuddinacb3e322008-06-25 18:18:32 +0000106 if (float(pesq_res) >= PESQ_THRESHOLD):
Nanang Izzuddin6ee166d2008-06-26 12:26:52 +0000107 endpt.trace("Success, PESQ result = " + pesq_res)
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +0000108 else:
Nanang Izzuddin6ee166d2008-06-26 12:26:52 +0000109 endpt.trace("Failed, PESQ result = " + pesq_res)
Nanang Izzuddinb6133fb2008-06-20 21:45:50 +0000110 raise TestError("WAV seems to be degraded badly")
111
112
113# Here where it all comes together
114test = cfg_file.test_param
115test.test_func = test_func
116test.post_func = post_func
117test.user_data = mod_pesq_user_data()
118