blob: ec9d15d4fa0ee707818b0c12a5b4192f199ea485 [file] [log] [blame]
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import logging
import re
import subprocess
import utils
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.audio import audio_helper
_DEFAULT_CARD = '0'
_DEFAULT_VOLUME_LEVEL = 100
_DEFAULT_CAPTURE_GAIN = 2500
_AUDIO_NOT_FOUND = r'Audio\snot\sdetected'
_MEASURED_LATENCY = r'Measured\sLatency:\s(\d+)\suS'
_REPORTED_LATENCY = r'Reported\sLatency:\s(\d+)\suS'
class audiovideo_LoopbackLatency(test.test):
version = 1
def initialize(self,
card=_DEFAULT_CARD,
default_volume_level=_DEFAULT_VOLUME_LEVEL,
default_capture_gain=_DEFAULT_CAPTURE_GAIN):
'''Setup the deps for the test.
Args:
card: The index of the sound card to use.
default_volume_level: The default volume level.
defalut_capture_gain: The default capture gain.
Raises: error.TestError if the deps can't be run
'''
self._card = card
self._volume_level = default_volume_level
self._capture_gain = default_capture_gain
self._ah = audio_helper.AudioHelper(self)
self._ah.setup_deps(['audioloop'])
super(audiovideo_LoopbackLatency, self).initialize()
def run_once(self):
self._ah.set_volume_levels(self._volume_level, self._capture_gain)
self._loopback_latency_path = os.path.join(self.autodir, 'deps',
'audioloop', 'src', 'loopback_latency')
noise_threshold = 400
measured_latency = None
reported_latency = None
deviation = None
while True:
cmdargs = [self._loopback_latency_path, '-n', str(noise_threshold)]
proc = subprocess.Popen(cmdargs, stdout=subprocess.PIPE)
audio_detected = True
# Parse loopback_latency output
while True:
line = proc.stdout.readline()
if not line:
break
match = re.search(_MEASURED_LATENCY, line, re.I)
if match:
measured_latency = int(match.group(1))
match = re.search(_REPORTED_LATENCY, line, re.I)
if match:
reported_latency = int(match.group(1))
if re.search(_AUDIO_NOT_FOUND, line, re.I):
audio_detected = False
if measured_latency and reported_latency:
deviation = (1.0 * abs(measured_latency - reported_latency) /
reported_latency)
logging.info('Tested with threshold %d.\nMeasured %d, reported '
'%d uS, deviation %f%%\n' %
(noise_threshold, measured_latency,
reported_latency, deviation * 100))
if not audio_detected:
logging.info('Audio not detected.')
break
noise_threshold *= 2
if deviation is None:
raise error.TestError('No audio detected')
elif deviation > .02:
raise error.TestError('Latency deviation(%f) too much, measured %d,'
' reported %d\n' %
(deviation, measured_latency,
reported_latency))