1#!/usr/bin/env python 2# Copyright (c) 2012 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Audio basic playback test. Verifies basic audio output. 7 8The tests plays an audio file and records its output while playing. It uses 9SOX tool to eliminate silence from begining and end of audio recorded. Then it 10uses PESQ tool to verify the recorded audio against expected file. 11 12The output of PESQ is a pair of numbers between 0 and 5 describing how close the 13recorded audio is to its reference file. 14 15The output of this test are the PESQ values that are graphed, example: 16RESULT audio_pesq: ref= 4.498 score 17RESULT audio_pesq: actual= 4.547 score 18""" 19 20import logging 21import os 22import sys 23import tempfile 24 25import audio_tools 26import pyauto_media 27import pyauto 28import pyauto_utils 29 30 31_TEST_HTML_PATH = pyauto.PyUITest.GetFileURLForDataPath('media', 'html', 32 'audio_record.html') 33_MEDIA_PATH = os.path.abspath(os.path.join(pyauto.PyUITest.DataDir(), 34 'pyauto_private', 'media')) 35 36# The media file to play. 37_TEST_AUDIO = pyauto.PyUITest.GetFileURLForPath(_MEDIA_PATH, 'dance2_10sec.wav') 38# The recording duration should be at least as the media duration. We use 5 39# extra seconds of record in this test. 40_RECORD_DURATION = 15 41 42# Due to different noise introduced by audio recording tools on windows and 43# linux, we require an expected audio file per platform. 44if 'win32' in sys.platform: 45 _TEST_EXPECTED_AUDIO = os.path.join(_MEDIA_PATH, 'audio_record_win.wav') 46else: 47 _TEST_EXPECTED_AUDIO = os.path.join(_MEDIA_PATH, 'audio_record_lin.wav') 48 49 50def GetTempFilename(): 51 """Returns an absolute path to an empty temp file.""" 52 f, path = tempfile.mkstemp(suffix='_actual.wav') 53 os.close(f) 54 return path 55 56 57class AudioRecordPerfTest(pyauto.PyUITest): 58 """PyAuto test container. See file doc string for more information.""" 59 60 def testBasicAudioPlaybackRecord(self): 61 """Plays an audio file and verifies its output against expected.""" 62 # The 2 temp files that will be potentially used in the test. 63 temp_file = None 64 file_no_silence = None 65 # Rebase test expectation file is REBASE=1 env variable is set. 66 rebase = 'REBASE' in os.environ 67 68 try: 69 temp_file = GetTempFilename() 70 record_thread = audio_tools.AudioRecorderThread(_RECORD_DURATION, 71 temp_file) 72 record_thread.start() 73 self.NavigateToURL(_TEST_HTML_PATH) 74 self.assertTrue(self.ExecuteJavascript("startTest('%s');" % _TEST_AUDIO)) 75 record_thread.join() 76 77 if record_thread.error: 78 self.fail(record_thread.error) 79 file_no_silence = _TEST_EXPECTED_AUDIO if rebase else GetTempFilename() 80 audio_tools.RemoveSilence(temp_file, file_no_silence) 81 82 # Exit if we just want to rebase expected output. 83 if rebase: 84 return 85 86 pesq_values = audio_tools.RunPESQ(_TEST_EXPECTED_AUDIO, file_no_silence) 87 if not pesq_values: 88 self.fail('Test failed to get pesq results.') 89 pyauto_utils.PrintPerfResult('audio_pesq', 'ref', pesq_values[0], 'score') 90 pyauto_utils.PrintPerfResult('audio_pesq', 'actual', pesq_values[1], 91 'score') 92 except: 93 logging.error('Test failed: %s', self.GetDOMValue('error')) 94 finally: 95 # Delete the temporary files used by the test. 96 if temp_file: 97 os.remove(temp_file) 98 if not rebase and file_no_silence: 99 os.remove(file_no_silence) 100 101 102if __name__ == '__main__': 103 pyauto_media.Main() 104