1# Copyright 2015 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"""This is a server side external microphone test using the Chameleon board.""" 5 6import logging 7import os 8import time 9 10from autotest_lib.client.common_lib import error 11from autotest_lib.client.cros.audio import audio_test_data 12from autotest_lib.client.cros.chameleon import audio_test_utils 13from autotest_lib.client.cros.chameleon import chameleon_audio_ids 14from autotest_lib.client.cros.chameleon import chameleon_audio_helper 15from autotest_lib.server.cros.audio import audio_test 16 17 18class audio_AudioBasicExternalMicrophone(audio_test.AudioTest): 19 """Server side external microphone audio test. 20 21 This test talks to a Chameleon board and a Cros device to verify 22 external mic audio function of the Cros device. 23 24 """ 25 version = 1 26 DELAY_BEFORE_RECORD_SECONDS = 0.5 27 RECORD_SECONDS = 9 28 DELAY_AFTER_BINDING = 0.5 29 30 def run_once(self, check_quality=False): 31 """Running basic headphone audio tests. 32 33 @param check_quality: flag to check audio quality. 34 35 """ 36 if not audio_test_utils.has_audio_jack(self.host): 37 raise error.TestNAError( 38 'No audio jack for the DUT.' 39 'Please check label of the host and control file.' 40 'Please check the host label and test dependency.') 41 42 golden_file = audio_test_data.SIMPLE_FREQUENCY_TEST_1330_FILE 43 44 source = self.widget_factory.create_widget( 45 chameleon_audio_ids.ChameleonIds.LINEOUT) 46 recorder = self.widget_factory.create_widget( 47 chameleon_audio_ids.CrosIds.EXTERNAL_MIC) 48 binder = self.widget_factory.create_binder(source, recorder) 49 50 with chameleon_audio_helper.bind_widgets(binder): 51 # Checks the node selected by cras is correct. 52 time.sleep(self.DELAY_AFTER_BINDING) 53 54 audio_test_utils.dump_cros_audio_logs( 55 self.host, self.facade, self.resultsdir, 'after_binding') 56 57 # Selects and checks the node selected by cras is correct. 58 audio_test_utils.check_and_set_chrome_active_node_types( 59 self.facade, None, 'MIC') 60 61 logging.info('Setting playback data on Chameleon') 62 source.set_playback_data(golden_file) 63 64 # Starts playing, waits for some time, and then starts recording. 65 # This is to avoid artifact caused by chameleon codec initialization 66 # in the beginning of playback. 67 logging.info('Start playing %s from Chameleon', golden_file.path) 68 source.start_playback() 69 70 time.sleep(self.DELAY_BEFORE_RECORD_SECONDS) 71 logging.info('Start recording from Cros device.') 72 recorder.start_recording() 73 74 time.sleep(self.RECORD_SECONDS) 75 76 recorder.stop_recording() 77 logging.info('Stopped recording from Cros device.') 78 79 audio_test_utils.dump_cros_audio_logs( 80 self.host, self.facade, self.resultsdir, 'after_recording') 81 82 recorder.read_recorded_binary() 83 logging.info('Read recorded binary from Cros device.') 84 85 recorded_file = os.path.join(self.resultsdir, "recorded.raw") 86 logging.info('Saving recorded data to %s', recorded_file) 87 recorder.save_file(recorded_file) 88 89 # Removes the beginning of recorded data. This is to avoid artifact 90 # caused by Cros device codec initialization in the beginning of 91 # recording. 92 recorder.remove_head(4.5) 93 94 recorded_file = os.path.join(self.resultsdir, "recorded_clipped.raw") 95 logging.info('Saving clipped data to %s', recorded_file) 96 recorder.save_file(recorded_file) 97 98 # Compares data by frequency. Audio signal from Chameleon Line-Out to 99 # Cros device external microphone has gone through analog processing. 100 # This suffers from codec artifacts and noise on the path. 101 # Comparing data by frequency is more robust than comparing them by 102 # correlation, which is suitable for fully-digital audio path like USB 103 # and HDMI. 104 audio_test_utils.check_recorded_frequency( 105 golden_file, 106 recorder, 107 check_artifacts=check_quality, 108 ignore_frequencies=[50, 60]) 109