diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2008-06-27 16:18:13 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2008-06-27 16:18:13 +0000 |
commit | cc9f73832038bdab140af1818635f15a391f3398 (patch) | |
tree | c5e14fbff6d3c3f1c9f97fc25ba19d56da96123c | |
parent | 41171475ee587b18522664d5db1cdb2b7604d0f4 (diff) |
Ticket #543:
- Fixed bug of calculating clock interval which should include channel count
- Added L16 codecs including stereo
- Added WAV files for stereo tests
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2075 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r-- | pjmedia/include/pjmedia/clock.h | 6 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/clock_thread.c | 4 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/master_port.c | 17 | ||||
-rw-r--r-- | pjsip-apps/src/test-pjsua/mod_pesq.py | 38 | ||||
-rw-r--r-- | pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000.py | 19 | ||||
-rw-r--r-- | pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000_stereo.py | 19 | ||||
-rw-r--r-- | pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000.py | 19 | ||||
-rw-r--r-- | pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000_stereo.py | 19 | ||||
-rw-r--r-- | pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000.py | 17 | ||||
-rw-r--r-- | pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000_stereo.py | 17 | ||||
-rw-r--r-- | pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000.py | 17 | ||||
-rw-r--r-- | pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000_stereo.py | 17 | ||||
-rw-r--r-- | pjsip-apps/src/test-pjsua/wavs/input.2.16.wav | bin | 0 -> 269060 bytes | |||
-rw-r--r-- | pjsip-apps/src/test-pjsua/wavs/input.2.8.wav | bin | 0 -> 134552 bytes |
14 files changed, 189 insertions, 20 deletions
diff --git a/pjmedia/include/pjmedia/clock.h b/pjmedia/include/pjmedia/clock.h index 30d98f84..abe43144 100644 --- a/pjmedia/include/pjmedia/clock.h +++ b/pjmedia/include/pjmedia/clock.h @@ -121,9 +121,10 @@ typedef void pjmedia_clock_callback(const pj_timestamp *ts, * * @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. * @param user_data User data, which will be passed to the callback. @@ -134,6 +135,7 @@ typedef void pjmedia_clock_callback(const pj_timestamp *ts, */ PJ_DECL(pj_status_t) pjmedia_clock_create( pj_pool_t *pool, unsigned clock_rate, + unsigned channel_count, unsigned samples_per_frame, unsigned options, pjmedia_clock_callback *cb, diff --git a/pjmedia/src/pjmedia/clock_thread.c b/pjmedia/src/pjmedia/clock_thread.c index 9329bc2b..457e58b0 100644 --- a/pjmedia/src/pjmedia/clock_thread.c +++ b/pjmedia/src/pjmedia/clock_thread.c @@ -55,6 +55,7 @@ static int clock_thread(void *arg); */ PJ_DEF(pj_status_t) pjmedia_clock_create( pj_pool_t *pool, unsigned clock_rate, + unsigned channel_count, unsigned samples_per_frame, unsigned options, pjmedia_clock_callback *cb, @@ -74,7 +75,8 @@ PJ_DEF(pj_status_t) pjmedia_clock_create( pj_pool_t *pool, if (status != PJ_SUCCESS) 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; clock->max_jump = MAX_JUMP_MSEC * clock->freq.u64 / 1000; diff --git a/pjmedia/src/pjmedia/master_port.c b/pjmedia/src/pjmedia/master_port.c index 6ab95215..b264dec9 100644 --- a/pjmedia/src/pjmedia/master_port.c +++ b/pjmedia/src/pjmedia/master_port.c @@ -52,6 +52,7 @@ PJ_DEF(pj_status_t) pjmedia_master_port_create( pj_pool_t *pool, { pjmedia_master_port *m; unsigned clock_rate; + unsigned channel_count; unsigned samples_per_frame; unsigned bytes_per_frame; pj_status_t status; @@ -64,15 +65,20 @@ PJ_DEF(pj_status_t) pjmedia_master_port_create( pj_pool_t *pool, PJ_ASSERT_RETURN(u_port->info.clock_rate == d_port->info.clock_rate, 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); + /* Get clock_rate and samples_per_frame from one of the port. */ clock_rate = u_port->info.clock_rate; samples_per_frame = u_port->info.samples_per_frame; + channel_count = u_port->info.channel_count; /* Get the bytes_per_frame value, to determine the size of the @@ -102,8 +108,9 @@ PJ_DEF(pj_status_t) pjmedia_master_port_create( pj_pool_t *pool, return status; /* 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); return status; diff --git a/pjsip-apps/src/test-pjsua/mod_pesq.py b/pjsip-apps/src/test-pjsua/mod_pesq.py index ef76def3..9853a756 100644 --- a/pjsip-apps/src/test-pjsua/mod_pesq.py +++ b/pjsip-apps/src/test-pjsua/mod_pesq.py @@ -49,12 +49,35 @@ def test_func(t, user_data): # Get output file name 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"): raise TestError("PESQ only works on clock rate 8kHz or 16kHz, clock rate used = "+clock_rate+ "kHz") @@ -62,15 +85,6 @@ def test_func(t, user_data): # 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 ua1.send("m") ua1.send(t.inst_params[1].uri) @@ -109,7 +123,7 @@ def post_func(t, user_data): pesq_out = pesq_proc.communicate() # 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") diff --git a/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000.py b/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000.py new file mode 100644 index 00000000..691a362a --- /dev/null +++ b/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000.py @@ -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 diff --git a/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000_stereo.py b/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000_stereo.py new file mode 100644 index 00000000..406a1826 --- /dev/null +++ b/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_16000_stereo.py @@ -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 diff --git a/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000.py b/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000.py new file mode 100644 index 00000000..df05a9da --- /dev/null +++ b/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000.py @@ -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 diff --git a/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000_stereo.py b/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000_stereo.py new file mode 100644 index 00000000..b114a1ab --- /dev/null +++ b/pjsip-apps/src/test-pjsua/scripts-pesq/200_codec_l16_8000_stereo.py @@ -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 diff --git a/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000.py b/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000.py new file mode 100644 index 00000000..a71004cf --- /dev/null +++ b/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000.py @@ -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 diff --git a/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000_stereo.py b/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000_stereo.py new file mode 100644 index 00000000..c20bc5fc --- /dev/null +++ b/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_16000_stereo.py @@ -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 diff --git a/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000.py b/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000.py new file mode 100644 index 00000000..d404f2d7 --- /dev/null +++ b/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000.py @@ -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 diff --git a/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000_stereo.py b/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000_stereo.py new file mode 100644 index 00000000..a40cd7e8 --- /dev/null +++ b/pjsip-apps/src/test-pjsua/scripts-pesq/201_codec_l16_8000_stereo.py @@ -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 diff --git a/pjsip-apps/src/test-pjsua/wavs/input.2.16.wav b/pjsip-apps/src/test-pjsua/wavs/input.2.16.wav Binary files differnew file mode 100644 index 00000000..a885fe98 --- /dev/null +++ b/pjsip-apps/src/test-pjsua/wavs/input.2.16.wav diff --git a/pjsip-apps/src/test-pjsua/wavs/input.2.8.wav b/pjsip-apps/src/test-pjsua/wavs/input.2.8.wav Binary files differnew file mode 100644 index 00000000..95b2310d --- /dev/null +++ b/pjsip-apps/src/test-pjsua/wavs/input.2.8.wav |