Add comparison to e2e and clean up.

BUG=issue502
TEST=manual

Review URL: https://webrtc-codereview.appspot.com/577006

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2274 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
andrew@webrtc.org 2012-05-23 02:47:58 +00:00
parent a1a34d675f
commit 2b004655b5
2 changed files with 81 additions and 49 deletions

View File

@ -18,7 +18,9 @@
#include "src/voice_engine/main/interface/voe_audio_processing.h"
#include "src/voice_engine/main/interface/voe_base.h"
#include "src/voice_engine/main/interface/voe_codec.h"
#include "src/voice_engine/main/interface/voe_hardware.h"
DEFINE_string(render, "render", "render device name");
DEFINE_string(codec, "ISAC", "codec name");
DEFINE_int32(rate, 16000, "codec sample rate in Hz");
@ -34,6 +36,8 @@ void RunHarness() {
ASSERT_TRUE(base != NULL);
VoECodec* codec = VoECodec::GetInterface(voe);
ASSERT_TRUE(codec != NULL);
VoEHardware* hardware = VoEHardware::GetInterface(voe);
ASSERT_TRUE(hardware != NULL);
ASSERT_EQ(0, base->Init());
int channel = base->CreateChannel();
@ -54,6 +58,23 @@ void RunHarness() {
ASSERT_TRUE(codec_found);
ASSERT_EQ(0, codec->SetSendCodec(channel, codec_params));
int num_devices = 0;
ASSERT_EQ(0, hardware->GetNumOfPlayoutDevices(num_devices));
char device_name[128] = {0};
char guid[128] = {0};
bool device_found = false;
int device_index;
for (device_index = 0; device_index < num_devices; device_index++) {
ASSERT_EQ(0, hardware->GetPlayoutDeviceName(device_index, device_name,
guid));
if (FLAGS_render.compare(device_name) == 0) {
device_found = true;
break;
}
}
ASSERT_TRUE(device_found);
ASSERT_EQ(0, hardware->SetPlayoutDevice(device_index));
// Disable all audio processing.
ASSERT_EQ(0, audio->SetAgcStatus(false));
ASSERT_EQ(0, audio->SetEcStatus(false));

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python
#
# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
@ -7,16 +8,6 @@
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
__author__ = 'andrew@webrtc.org (Andrew MacDonald)'
import optparse
import os
import shlex
import subprocess
import sys
import threading
import time
"""Runs an end-to-end audio quality test on Linux.
Expects the presence of PulseAudio virtual devices (null sinks). These are
@ -26,18 +17,14 @@ utility (pacat) is used to play to and record from the virtual devices.
The input reference file is then compared to the output file.
"""
def popen_and_call(popen_args, call_on_exit):
"""Executes the arguments, and triggers the callback when finished."""
def run_in_thread(popen_args, call_on_exit):
proc = subprocess.Popen(popen_args)
proc.wait()
call_on_exit()
return
thread = threading.Thread(target=run_in_thread,
args=(popen_args, call_on_exit))
thread.start()
return thread
import optparse
import os
import re
import shlex
import subprocess
import sys
import threading
import time
def main(argv):
parser = optparse.OptionParser()
@ -53,42 +40,66 @@ def main(argv):
parser.add_option('--rec_sink', default='render',
help='name of PulseAudio sink whose monitor will be recorded')
parser.add_option('--harness',
default=os.path.dirname(sys.argv[0]) +
'/../../../out/Debug/audio_e2e_harness',
default=os.path.abspath(os.path.dirname(sys.argv[0]) +
'/../../../out/Debug/audio_e2e_harness'),
help='path to audio harness executable')
parser.add_option('--compare',
help='command-line arguments for comparison tool')
parser.add_option('--regexp',
help='regular expression to extract the comparison metric')
(options, args) = parser.parse_args(argv[1:])
# Set default devices to be used by VoiceEngine.
subprocess.call(['pacmd', 'set-default-sink', options.rec_sink]);
subprocess.call(['pacmd', 'set-default-source',
options.play_sink + '.monitor']);
# Set the default capture device to be used by VoiceEngine. We unfortunately
# need to do this rather than select the devices directly through the harness
# because monitor sources don't appear in VoiceEngine except as defaults.
#
# We pass the render device for VoiceEngine to select because (for unknown
# reasons) the virtual device is sometimes not used when the default.
retcode = subprocess.call(['pacmd', 'set-default-source',
options.play_sink + '.monitor'], stdout=subprocess.PIPE);
if retcode != 0:
return retcode
print 'Start an audio call'
print options.harness
voe_proc = subprocess.Popen([options.harness,
'--codec=' + options.codec, '--rate=' + options.rate]);
command = [options.harness, '--render=' + options.rec_sink,
'--codec=' + options.codec, '--rate=' + options.rate]
print ' '.join(command)
voe_proc = subprocess.Popen(command)
print 'Start recording to ' + options.output
format_args = ('-n --format=s16le --rate=' + options.rate + ' --channels=' +
options.channels + ' --raw')
command = ('pacat -r -d ' + options.rec_sink + '.monitor ' + format_args +
' ' + options.output)
record_proc = subprocess.Popen(shlex.split(command))
def stop_recording():
record_proc.kill()
format_args = ['-n', '--format=s16le', '--rate=' + options.rate,
'--channels=' + options.channels, '--raw']
command = (['pacat', '-p', '-d', options.play_sink] + format_args +
[options.input])
print ' '.join(command)
play_proc = subprocess.Popen(command)
print 'Start playing from ' + options.input
command = ('pacat -p -d ' + options.play_sink + ' ' + format_args + ' ' +
options.input)
popen_and_call(shlex.split(command), stop_recording)
# If recording starts before there is data available, pacat sometimes
# inexplicably adds a large delay to the start of the file. We wait here in
# an attempt to prevent that.
time.sleep(0.2)
command = (['pacat', '-r', '-d', options.rec_sink + '.monitor'] +
format_args + [options.output])
print ' '.join(command)
record_proc = subprocess.Popen(command)
# record_proc will be killed after playout finishes.
record_proc.wait()
print 'Shutdown audio call'
retcode = play_proc.wait()
# If these ended early, an exception will be thrown here.
record_proc.kill()
voe_proc.kill()
if retcode != 0:
return retcode
# TODO(andrew): compare files.
if options.compare and options.regexp:
command = shlex.split(options.compare) + [options.input, options.output]
print ' '.join(command)
compare_proc = subprocess.Popen(command, stdout=subprocess.PIPE)
compare_output = compare_proc.communicate()[0]
if compare_proc.returncode != 0:
return compare_proc.returncode
# The list should only contain one item.
print ''.join(re.findall(options.regexp, compare_output))
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))