audio_helper: Migrate audio tools

Audio tools(test_tones, audioloop, sox) are moved from
autotest to platform/audiotest, which are installed to
/usr/bin/ by default for test and factory image.

For autotest, clean up code to setup each deps and refer to
executables through audio_helper.
For factory test, the plan is to decouple from autotest and
migrate to platform/factory, they'll call each audio tool
directly.

BUG=chrome-os-partner:21686
CQ-DEPEND=CL:66189
TEST=Manual run all modified tests.

Change-Id: I1dbd1f3557f30679f625843f3bf9e697d80ccb5a
Reviewed-on: https://chromium-review.googlesource.com/168427
Reviewed-by: Dean Liao <deanliao@chromium.org>
Reviewed-by: Rohit Makasana <rohitbm@chromium.org>
Reviewed-by: Hsinyu Chao <hychao@chromium.org>
Tested-by: Hsinyu Chao <hychao@chromium.org>
Commit-Queue: Hsinyu Chao <hychao@chromium.org>
diff --git a/client/cros/audio/audio_helper.py b/client/cros/audio/audio_helper.py
index a447186..556d771 100644
--- a/client/cros/audio/audio_helper.py
+++ b/client/cros/audio/audio_helper.py
@@ -36,6 +36,14 @@
 _MEASURED_LATENCY_RE = r'Measured\sLatency:\s(\d+)\suS'
 _REPORTED_LATENCY_RE = r'Reported\sLatency:\s(\d+)\suS'
 
+# Tools from platform/audiotest
+AUDIOFUNTEST_PATH = 'audiofuntest'
+AUDIOLOOP_PATH = 'looptest'
+LOOPBACK_LATENCY_PATH = 'loopback_latency'
+SOX_PATH = 'sox'
+TEST_TONES_PATH = 'test_tones'
+
+
 class RecordSampleThread(threading.Thread):
     '''Wraps the execution of arecord in a thread.'''
     def __init__(self, audio, recordfile):
@@ -78,51 +86,6 @@
         self._num_channels = num_channels
         self._mix_cmd = mix_command
 
-    def setup_deps(self, deps):
-        '''
-        Sets up audio related dependencies.
-
-        @param deps: List of dependencies to set up.
-        '''
-        for dep in deps:
-            if dep == 'test_tones':
-                dep_dir = os.path.join(self._test.autodir, 'deps', dep)
-                self._test.job.install_pkg(dep, 'dep', dep_dir)
-                self.test_tones_path = os.path.join(dep_dir, 'src', dep)
-            elif dep == 'audioloop':
-                dep_dir = os.path.join(self._test.autodir, 'deps', dep)
-                self._test.job.install_pkg(dep, 'dep', dep_dir)
-                self.audioloop_path = os.path.join(dep_dir, 'src',
-                        'looptest')
-                self.loopback_latency_path = os.path.join(dep_dir, 'src',
-                        'loopback_latency')
-            elif dep == 'sox':
-                dep_dir = os.path.join(self._test.autodir, 'deps', dep)
-                self._test.job.install_pkg(dep, 'dep', dep_dir)
-                self.sox_path = os.path.join(dep_dir, 'bin', dep)
-                self.sox_lib_path = os.path.join(dep_dir, 'lib')
-                if os.environ.has_key(LD_LIBRARY_PATH):
-                    paths = os.environ[LD_LIBRARY_PATH].split(':')
-                    if not self.sox_lib_path in paths:
-                        paths.append(self.sox_lib_path)
-                        os.environ[LD_LIBRARY_PATH] = ':'.join(paths)
-                else:
-                    os.environ[LD_LIBRARY_PATH] = self.sox_lib_path
-
-    def cleanup_deps(self, deps):
-        '''
-        Cleans up environments which has been setup for dependencies.
-
-        @param deps: List of dependencies to clean up.
-        '''
-        for dep in deps:
-            if dep == 'sox':
-                if (os.environ.has_key(LD_LIBRARY_PATH)
-                        and hasattr(self, 'sox_lib_path')):
-                    paths = filter(lambda x: x != self.sox_lib_path,
-                            os.environ[LD_LIBRARY_PATH].split(':'))
-                    os.environ[LD_LIBRARY_PATH] = ':'.join(paths)
-
     def set_volume_levels(self, volume, capture):
         '''
         Sets the volume and capture gain through cras_test_client
@@ -263,7 +226,7 @@
         @return The output of sox stat command
         '''
         sox_mixer_cmd = self.get_sox_mixer_cmd(infile, channel)
-        stat_cmd = '%s -c 1 %s - -n stat 2>&1' % (self.sox_path,
+        stat_cmd = '%s -c 1 %s - -n stat 2>&1' % (SOX_PATH,
                 self._sox_format)
         sox_cmd = '%s | %s' % (sox_mixer_cmd, stat_cmd)
         return utils.system_output(sox_cmd, retain_output=True)
@@ -311,7 +274,7 @@
             else:
                 pan_values = '%s%s' % (pan_values, ',0')
 
-        return '%s -c 2 %s %s -c 1 %s - mixer %s' % (self.sox_path,
+        return '%s -c 2 %s %s -c 1 %s - mixer %s' % (SOX_PATH,
                 self._sox_format, infile, self._sox_format, pan_values)
 
     def noise_reduce_file(self, in_file, noise_file, out_file):
@@ -325,10 +288,10 @@
 
         @return The name of the file containing the noise-reduced data.
         '''
-        prof_cmd = '%s -c 2 %s %s -n noiseprof' % (self.sox_path,
+        prof_cmd = '%s -c 2 %s %s -n noiseprof' % (SOX_PATH,
                 _SOX_FORMAT, noise_file)
         reduce_cmd = ('%s -c 2 %s %s -c 2 %s %s noisered' %
-                (self.sox_path, _SOX_FORMAT, in_file, _SOX_FORMAT, out_file))
+                (SOX_PATH, _SOX_FORMAT, in_file, _SOX_FORMAT, out_file))
         utils.system('%s | %s' % (prof_cmd, reduce_cmd))
 
     def record_sample(self, tmpfile):
@@ -437,7 +400,7 @@
         '''
         noise_threshold = str(args['n']) if args.has_key('n') else '400'
 
-        cmd = '%s -n %s' % (self.loopback_latency_path, noise_threshold)
+        cmd = '%s -n %s' % (LOOPBACK_LATENCY_PATH, noise_threshold)
 
         output = utils.system_output(cmd, retain_output=True)
 
@@ -489,7 +452,7 @@
         @param duration: duration of the generated sine tone.
         @param sample_size: output audio sample size. Default to 16.
         '''
-        cmdargs = [self.sox_path, '-b', str(sample_size), '-n', '-t', 'alsa',
+        cmdargs = [SOX_PATH, '-b', str(sample_size), '-n', '-t', 'alsa',
                    odev, 'synth', str(duration)]
         if channel == 0:
             cmdargs += ['sine', str(freq), 'sine', '0']
diff --git a/client/site_tests/audio_SuspendResumeStress/audio_SuspendResumeStress.py b/client/site_tests/audio_SuspendResumeStress/audio_SuspendResumeStress.py
index 1f4ce62..cd624d6 100644
--- a/client/site_tests/audio_SuspendResumeStress/audio_SuspendResumeStress.py
+++ b/client/site_tests/audio_SuspendResumeStress/audio_SuspendResumeStress.py
@@ -41,7 +41,6 @@
         self._ah = audio_helper.AudioHelper(self,
                 record_command=cmd_rec,
                 num_channels=num_channels)
-        self._ah.setup_deps(['audioloop', 'sox'])
         self._suspender = power_suspend.Suspender(self.resultsdir,
                                                   method=sys_power.do_suspend)
 
diff --git a/client/site_tests/audiovideo_CRASFormatConversion/audiovideo_CRASFormatConversion.py b/client/site_tests/audiovideo_CRASFormatConversion/audiovideo_CRASFormatConversion.py
index b36463d..65000fb 100755
--- a/client/site_tests/audiovideo_CRASFormatConversion/audiovideo_CRASFormatConversion.py
+++ b/client/site_tests/audiovideo_CRASFormatConversion/audiovideo_CRASFormatConversion.py
@@ -44,7 +44,6 @@
         self._ah = audio_helper.AudioHelper(self,
                                             record_command = cmd_rec,
                                             sox_threshold = _MIN_SOX_RMS_VALUE)
-        self._ah.setup_deps(['sox'])
         self._sox_min_rms = _MIN_SOX_RMS_VALUE
         super(audiovideo_CRASFormatConversion, self).initialize()
 
diff --git a/client/site_tests/audiovideo_LineOutToMicInLoopback/audiovideo_LineOutToMicInLoopback.py b/client/site_tests/audiovideo_LineOutToMicInLoopback/audiovideo_LineOutToMicInLoopback.py
index ef9c660..55bfd1c 100755
--- a/client/site_tests/audiovideo_LineOutToMicInLoopback/audiovideo_LineOutToMicInLoopback.py
+++ b/client/site_tests/audiovideo_LineOutToMicInLoopback/audiovideo_LineOutToMicInLoopback.py
@@ -42,7 +42,6 @@
 
         self._ah = audio_helper.AudioHelper(self,
                 num_channels=self._num_channels)
-        self._ah.setup_deps(['sox', 'audioloop'])
 
         super(audiovideo_LineOutToMicInLoopback, self).initialize()
 
diff --git a/client/site_tests/audiovideo_LoopbackLatency/audiovideo_LoopbackLatency.py b/client/site_tests/audiovideo_LoopbackLatency/audiovideo_LoopbackLatency.py
index 1a6998e..aafa064 100755
--- a/client/site_tests/audiovideo_LoopbackLatency/audiovideo_LoopbackLatency.py
+++ b/client/site_tests/audiovideo_LoopbackLatency/audiovideo_LoopbackLatency.py
@@ -34,7 +34,6 @@
         self._capture_gain = default_capture_gain
 
         self._ah = audio_helper.AudioHelper(self)
-        self._ah.setup_deps(['audioloop'])
 
         super(audiovideo_LoopbackLatency, self).initialize()
 
diff --git a/client/site_tests/audiovideo_PlaybackRecordSemiAuto/audiovideo_PlaybackRecordSemiAuto.py b/client/site_tests/audiovideo_PlaybackRecordSemiAuto/audiovideo_PlaybackRecordSemiAuto.py
index 47d861b..6310520 100644
--- a/client/site_tests/audiovideo_PlaybackRecordSemiAuto/audiovideo_PlaybackRecordSemiAuto.py
+++ b/client/site_tests/audiovideo_PlaybackRecordSemiAuto/audiovideo_PlaybackRecordSemiAuto.py
@@ -7,6 +7,7 @@
 from autotest_lib.client.bin import utils
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.cros import cros_ui, cros_ui_test, httpd
+from autotest_lib.client.cros.audio import audio_helper
 
 # HTML templates.
 _STATIC_CSS ='''
@@ -422,7 +423,6 @@
 
 
     def setup(self):
-        self.job.setup_dep(['test_tones'])
         # build alsa_caps as well.
         os.chdir(self.srcdir)
         utils.make('clean')
@@ -439,15 +439,6 @@
         logging.info('Test Definitions:')
         logging.info(self._pp.pformat(_TESTS))
 
-        dep = 'test_tones'
-        dep_dir = os.path.join(self.autodir, 'deps', dep)
-        self.job.install_pkg(dep, 'dep', dep_dir)
-        self._test_tones_path = os.path.join(dep_dir, 'src', dep)
-        if not (os.path.exists(self._test_tones_path) and
-                os.access(self._test_tones_path, os.X_OK)):
-            raise error.TestError(
-                    '%s is not an executable' % self._test_tones_path)
-
         self._alsa_caps_path = os.path.join(self.srcdir, 'alsa_caps')
         if not (os.path.exists(self._alsa_caps_path) and
                 os.access(self._alsa_caps_path, os.X_OK)):
@@ -1382,7 +1373,7 @@
                     active_channel: integer to select channel for playback.
                                     None means playback on all channels.
         """
-        args['exec'] = self._test_tones_path
+        args['exec'] = audio_helper.TEST_TONES_PATH
 
         if not 'tone_end_volume' in args:
             args['tone_end_volume'] = args['tone_volume']
diff --git a/client/site_tests/desktopui_AudioFeedback/desktopui_AudioFeedback.py b/client/site_tests/desktopui_AudioFeedback/desktopui_AudioFeedback.py
index f72202c..2e41bc3 100644
--- a/client/site_tests/desktopui_AudioFeedback/desktopui_AudioFeedback.py
+++ b/client/site_tests/desktopui_AudioFeedback/desktopui_AudioFeedback.py
@@ -46,7 +46,6 @@
                                             record_command=cmd_rec,
                                             num_channels=num_channels,
                                             mix_command=cmd_mix)
-        self._ah.setup_deps(['audioloop', 'sox'])
 
         super(desktopui_AudioFeedback, self).initialize()
 
diff --git a/client/site_tests/desktopui_MediaAudioFeedback/desktopui_MediaAudioFeedback.py b/client/site_tests/desktopui_MediaAudioFeedback/desktopui_MediaAudioFeedback.py
index d2ac27a..82ea705 100644
--- a/client/site_tests/desktopui_MediaAudioFeedback/desktopui_MediaAudioFeedback.py
+++ b/client/site_tests/desktopui_MediaAudioFeedback/desktopui_MediaAudioFeedback.py
@@ -64,7 +64,6 @@
                                             record_command=cmd_rec,
                                             num_channels=num_channels,
                                             mix_command=cmd_mix)
-        self._ah.setup_deps(['audioloop', 'sox'])
 
         super(desktopui_MediaAudioFeedback, self).initialize()
         self._test_url = 'http://localhost:8000/play.html'
diff --git a/client/site_tests/factory_AudioLoop/factory_AudioLoop.py b/client/site_tests/factory_AudioLoop/factory_AudioLoop.py
index b8dd0f5..698b1ea 100755
--- a/client/site_tests/factory_AudioLoop/factory_AudioLoop.py
+++ b/client/site_tests/factory_AudioLoop/factory_AudioLoop.py
@@ -94,7 +94,8 @@
         Stop capturing data
         '''
         factory.console.info('Run audiofuntest')
-        self._proc = subprocess.Popen([self._audiofuntest_path, '-r', '48000',
+        self._proc = subprocess.Popen([audio_helper.AUDIOFUNTEST_PATH,
+                                       '-r', '48000',
                                        '-i', idev, '-o', odev, '-l',
                                        '%d' % dur], stderr=subprocess.PIPE)
 
@@ -140,7 +141,6 @@
 
             # TODO(hychao): split deps and I/O devices to different
             # utils so we can setup deps only once.
-            self._ah.setup_deps(['sox'])
             for output_device in self._output_devices:
                 # Record a sample of "silence" to use as a noise profile.
                 with tempfile.NamedTemporaryFile(mode='w+t') as noise_file:
@@ -201,15 +201,6 @@
         if mixer_controls is not None:
             self._ah.set_mixer_controls(mixer_controls)
 
-        # Setup dependencies
-        self._ah.setup_deps(['sox', 'test_tones'])
-        self._audiofuntest_path = os.path.join(self.autodir, 'deps',
-                'test_tones', 'src', 'audiofuntest')
-        if not (os.path.exists(self._audiofuntest_path) and
-                os.access(self._audiofuntest_path, os.X_OK)):
-            raise error.TestError(
-                    '%s is not an executable' % self._audiofuntest_path)
-
         # Setup HTML UI, and event handler
         self.ui = UI()
         self.ui.AddEventHandler('start_run_test', self.start_run_test)
@@ -219,4 +210,3 @@
         self.ui.CallJSFunction('init', autostart, require_dongle)
         factory.console.info('Run UI')
         self.ui.Run()
-
diff --git a/client/site_tests/factory_AudioQuality/factory_AudioQuality.py b/client/site_tests/factory_AudioQuality/factory_AudioQuality.py
index f807fa4..d32df12 100644
--- a/client/site_tests/factory_AudioQuality/factory_AudioQuality.py
+++ b/client/site_tests/factory_AudioQuality/factory_AudioQuality.py
@@ -409,11 +409,12 @@
         self.restore_configuration()
         self.ui.CallJSFunction('setMessage', _LABEL_AUDIOLOOP)
         if self._use_sox_loop:
-            cmdargs = [self._ah.sox_path, '-t', 'alsa', self._input_dev, '-t',
-                    'alsa', self._output_dev]
+            cmdargs = [audio_helper.SOX_PATH, '-t', 'alsa',
+                       self._input_dev, '-t',
+                       'alsa', self._output_dev]
             self._loop_process = subprocess.Popen(cmdargs)
         else:
-            cmdargs = [self._ah.audioloop_path, '-i', self._input_dev, '-o',
+            cmdargs = [audio_helper.AUDIOLOOP_PATH, '-i', self._input_dev, '-o',
                     self._output_dev, '-c', str(self._loop_buffer_count)]
             self._loop_process = subprocess.Popen(cmdargs)
 
@@ -497,7 +498,6 @@
         utils.system('ifconfig %s down' % self._eth)
         utils.system('ifconfig %s up' % self._eth)
         self.restore_configuration()
-        self._ah.cleanup_deps(['sox', 'audioloop'])
 
     def mock_command(self, event):
         """Receive test command from FA-utility.
@@ -693,7 +693,6 @@
         logging.info('%s run_once', self.__class__)
 
         self._ah = audio_helper.AudioHelper(self)
-        self._ah.setup_deps(['sox', 'audioloop'])
         self._input_dev = input_dev
         self._output_dev = output_dev
         self._eth = None
diff --git a/client/site_tests/factory_Connector/factory_Connector.py b/client/site_tests/factory_Connector/factory_Connector.py
index 02b6cf3..a25878c 100644
--- a/client/site_tests/factory_Connector/factory_Connector.py
+++ b/client/site_tests/factory_Connector/factory_Connector.py
@@ -445,7 +445,6 @@
         '''
         factory.log('Start audiofuntest')
         errors = []
-        self._ah.setup_deps(['test_tones'])
         audiofuntest_path = os.path.join(self.autodir, 'deps',
                 'test_tones', 'src', 'audiofuntest')
         if not (os.path.exists(audiofuntest_path) and
@@ -481,7 +480,6 @@
         '''
         factory.log('Start audioloop')
         errors = []
-        self._ah.setup_deps(['sox'])
         self._ah.set_mixer_controls(
                 [{'name': '"Digital-Mic Capture Switch"',
                   'value': 'on'},
@@ -492,7 +490,7 @@
 
         # Callbacks for sound playback and record result check.
         def playback_sine():
-            cmd = '%s -n -d synth %d sine %d' % (self._ah.sox_path,
+            cmd = '%s -n -d synth %d sine %d' % (audio_helper.SOX_PATH,
                     loop_duration, test_freq)
             utils.system(cmd)