desktopui_AudioFeedback.py revision 78c44b20a094313d388a2f12536384178b2c339f
1# Copyright (c) 2012 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6 7from autotest_lib.client.common_lib import error 8from autotest_lib.client.cros import cros_ui_test, httpd 9from autotest_lib.client.cros.audio import audio_helper 10 11# Names of mixer controls. 12_CONTROL_MASTER = "'Master Playback Volume'" 13_CONTROL_HEADPHONE = "'Headphone Playback Volume'" 14_CONTROL_SPEAKER = "'Speaker Playback Volume'" 15_CONTROL_MIC_BOOST = "'Mic Boost Volume'" 16_CONTROL_MIC_CAPTURE = "'Mic Capture Volume'" 17_CONTROL_CAPTURE = "'Capture Volume'" 18_CONTROL_PCM = "'PCM Playback Volume'" 19_CONTROL_DIGITAL = "'Digital Capture Volume'" 20_CONTROL_CAPTURE_SWITCH = "'Capture Switch'" 21 22# Default test configuration. 23_DEFAULT_CARD = '0' 24_DEFAULT_MIXER_SETTINGS = [{'name': _CONTROL_MASTER, 'value': "100%"}, 25 {'name': _CONTROL_HEADPHONE, 'value': "100%"}, 26 {'name': _CONTROL_SPEAKER, 'value': "0%"}, 27 {'name': _CONTROL_MIC_BOOST, 'value': "50%"}, 28 {'name': _CONTROL_MIC_CAPTURE, 'value': "50%"}, 29 {'name': _CONTROL_PCM, 'value': "100%"}, 30 {'name': _CONTROL_DIGITAL, 'value': "100%"}, 31 {'name': _CONTROL_CAPTURE, 'value': "100%"}, 32 {'name': _CONTROL_CAPTURE_SWITCH, 'value': "on"}] 33 34_DEFAULT_NUM_CHANNELS = 2 35_DEFAULT_RECORD_DURATION = 15 36# Minimum RMS value to consider a "pass". 37_DEFAULT_SOX_RMS_THRESHOLD = 0.25 38_DEFAULT_VOLUME_LEVEL = 100 39_DEFAULT_CAPTURE_GAIN = 2500 40 41 42class desktopui_AudioFeedback(cros_ui_test.UITest): 43 """Verifies if youtube playback can be captured.""" 44 version = 1 45 46 def initialize(self, 47 card=_DEFAULT_CARD, 48 mixer_settings=_DEFAULT_MIXER_SETTINGS, 49 num_channels=_DEFAULT_NUM_CHANNELS, 50 record_duration=_DEFAULT_RECORD_DURATION, 51 sox_min_rms=_DEFAULT_SOX_RMS_THRESHOLD, 52 volume_level=_DEFAULT_VOLUME_LEVEL, 53 capture_gain=_DEFAULT_CAPTURE_GAIN): 54 """Setup the deps for the test. 55 56 Args: 57 card: The index of the sound card to use. 58 mixer_settings: Alsa control settings to apply to the mixer before 59 starting the test. 60 num_channels: The number of channels on the device to test. 61 record_duration: How long of a sample to record. 62 sox_min_rms: The minimum RMS value to consider a pass. 63 64 Raises: 65 error.TestError if the deps can't be run. 66 """ 67 self._card = card 68 self._mixer_settings = mixer_settings 69 self._volume_level = volume_level 70 self._capture_gain = capture_gain 71 72 cmd_rec = 'arecord -d %f -f dat' % record_duration 73 self._ah = audio_helper.AudioHelper(self, 74 record_command=cmd_rec, 75 sox_threshold=sox_min_rms, 76 num_channels=num_channels) 77 self._ah.setup_deps(['audioloop', 'sox']) 78 79 super(desktopui_AudioFeedback, self).initialize() 80 self._test_url = 'http://localhost:8000/youtube.html' 81 self._testServer = httpd.HTTPListener(8000, docroot=self.bindir) 82 self._testServer.run() 83 84 def run_once(self): 85 """Entry point of this test.""" 86 self._ah.set_volume_levels(self._volume_level, self._capture_gain) 87 if not self._ah.check_loopback_dongle(): 88 raise error.TestError('Audio loopback dongle is in bad state.') 89 90 # Record a sample of "silence" to use as a noise profile. 91 noise_file_name = self._ah.create_wav_file("noise") 92 self._ah.record_sample(noise_file_name) 93 94 # Play the same video to test all channels. 95 self.play_video(lambda: self._ah.loopback_test_channels( 96 noise_file_name)) 97 98 def play_video(self, player_ready_callback): 99 """Plays a Youtube video to record audio samples. 100 101 Skipping initial 60 seconds so we can ignore initial silence 102 in the video. 103 104 @param player_ready_callback: callback when yt player is ready. 105 """ 106 logging.info('Playing back youtube media file %s.', self._test_url) 107 self.pyauto.NavigateToURL(self._test_url) 108 109 # Default automation timeout is 45 seconds. 110 if not self.pyauto.WaitUntil(lambda: self.pyauto.ExecuteJavascript(""" 111 player_status = document.getElementById('player_status'); 112 window.domAutomationController.send(player_status.innerHTML); 113 """), expect_retval='player ready'): 114 raise error.TestError('Failed to load the Youtube player') 115 self.pyauto.ExecuteJavascript(""" 116 ytplayer.pauseVideo(); 117 ytplayer.seekTo(60, true); 118 ytplayer.playVideo(); 119 window.domAutomationController.send(''); 120 """) 121 if player_ready_callback: 122 player_ready_callback() 123