1# Copyright (c) 2014 The Chromium OS 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 6import os 7import tempfile 8 9from autotest_lib.client.bin import utils 10from autotest_lib.client.common_lib import error 11from autotest_lib.client.cros.audio import audio_helper 12from autotest_lib.client.cros.audio import cmd_utils 13from autotest_lib.client.cros.audio import cras_utils 14from autotest_lib.client.cros.audio import sox_utils 15 16 17NUMBER_OF_SEEKING = 6 18SEEKING_TIME = 50 19 20class audio_SeekAudioFeedback(audio_helper.chrome_rms_test): 21 """Verifies audio output on seeking forward/back.""" 22 23 version = 1 24 25 def run_once(self, test_file, test_duration): 26 self._rms_values = {} 27 noise_file = os.path.join(self.resultsdir, 'noise.wav') 28 noiseprof_file = tempfile.NamedTemporaryFile() 29 30 # Record a sample of "silence" to use as a noise profile. 31 cras_utils.capture(noise_file, duration=2) 32 sox_utils.noise_profile(noise_file, noiseprof_file.name) 33 34 # Open the test page 35 self.chrome.browser.platform.SetHTTPServerDirectories(self.bindir) 36 tab = self.chrome.browser.tabs[0] 37 tab.Navigate(self.chrome.browser.platform.http_server.UrlOf( 38 os.path.join(self.bindir, 'play.html'))) 39 tab.WaitForDocumentReadyStateToBeComplete() 40 41 # Test audio file. 42 self.rms_test(tab, test_file, noiseprof_file.name, test_duration) 43 self.write_perf_keyval(self._rms_values) 44 45 46 def rms_test(self, tab, test_file, noiseprof_file, test_duration): 47 logging.info('rms test on media file %s.', test_file) 48 recorded_file = os.path.join(self.resultsdir, 'recorded.wav') 49 loopback_file = os.path.join(self.resultsdir, 'loopback.wav') 50 51 52 # Plays the test_file in the browser and seek 6 times. 53 for x in range(0,NUMBER_OF_SEEKING): 54 self.play_media(tab, test_file, x) 55 # Record the audio output and also the CRAS loopback output. 56 p1 = cmd_utils.popen(cras_utils.capture_cmd( 57 recorded_file, duration=test_duration )) 58 p2 = cmd_utils.popen(cras_utils.loopback_cmd( 59 loopback_file, duration=test_duration )) 60 cmd_utils.wait_and_check_returncode(p1, p2) 61 62 # See if we recorded something. 63 64 # We captured two channels of audio in the CRAS loopback. 65 # The RMS values are for debugging only. 66 loopback_stats = [audio_helper.get_channel_sox_stat( 67 loopback_file, i) for i in (1, 2)] 68 logging.info('loopback stat: %s', [str(s) for s in loopback_stats]) 69 70 reduced_file = tempfile.NamedTemporaryFile() 71 sox_utils.noise_reduce( 72 recorded_file, reduced_file.name, noiseprof_file) 73 rms = audio_helper.get_rms(reduced_file.name)[0] 74 75 self._rms_values['%s_rms_value' % test_file.replace('.', '_')]=rms 76 77 78 def wait_player_end(self, tab): 79 """Wait for player ends playing.""" 80 utils.poll_for_condition( 81 condition=lambda: tab.EvaluateJavaScript('player.ended'), 82 exception=error.TestError('Player never end until timeout.')) 83 84 85 def play_media(self, tab, test_file, value): 86 """Plays a media file in Chromium. 87 88 @param test_file: Media file to test. 89 @param vlaue: Index of the loop 90 """ 91 tab.EvaluateJavaScript('play("%s")' % test_file) 92 def get_current_time(): 93 return tab.EvaluateJavaScript('player.currentTime') 94 95 if value <=(NUMBER_OF_SEEKING/2): 96 new_seek = (value * SEEKING_TIME) 97 else: 98 new_seek = (((NUMBER_OF_SEEKING - value) * SEEKING_TIME)) 99 # Make sure the audio is being played 100 old_time = get_current_time() 101 utils.poll_for_condition( 102 condition=lambda: get_current_time() > old_time, 103 exception=error.TestError('Player never start until timeout.')) 104 tab.EvaluateJavaScript('player.currentTime = %d' % new_seek) 105