Selects the card id on platforms with multiple cards.
On some platforms, there are more than one sound cards. And the default one is
not with index: 0. So, we need a way to figure out the correct card id we
should used.
TEST=run the test on butterfly
BUG=307384
Change-Id: I990c711c1e9fd4616797ad598687c80cb6e7eba8
Reviewed-on: https://chromium-review.googlesource.com/175420
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Commit-Queue: Owen Lin <owenlin@chromium.org>
Tested-by: Owen Lin <owenlin@chromium.org>
diff --git a/client/cros/audio/audio_helper.py b/client/cros/audio/audio_helper.py
index 8c190a2..3904f5e 100644
--- a/client/cros/audio/audio_helper.py
+++ b/client/cros/audio/audio_helper.py
@@ -6,6 +6,8 @@
import logging
import os
import re
+import shlex
+import subprocess
import threading
import time
@@ -473,3 +475,31 @@
check_recorded_callback(sox_output_reduced)
+def find_hw_soundcard_name(cpuType=None):
+ '''Finds the name of the default hardware soundcard.
+
+ @param cpuType: (Optional) the cpu type.
+ '''
+
+ if not cpuType:
+ cpuType = utils.get_cpu_arch()
+
+ # On Intel platform, return the name "PCH".
+ if cpuType == 'x86_64' or cpuType == 'i386':
+ return 'PCH'
+
+ # On other platforms, if there is only one card, choose it; otherwise,
+ # choose the first card with controls named 'Speaker'
+ cmd = 'amixer -c %d scontrols'
+ id = 0
+ while True:
+ p = subprocess.Popen(shlex.split(cmd % id), stdout=subprocess.PIPE)
+ output, error = p.communicate()
+ if p.wait() != 0: # end of the card list
+ break;
+ if 'speaker' in output.lower():
+ return str(id)
+ id = id + 1
+
+ # If there is only one soundcard, return it, else return not found (None)
+ return '0' if id == 1 else None
diff --git a/client/site_tests/audiovideo_Microphone/audiovideo_Microphone.py b/client/site_tests/audiovideo_Microphone/audiovideo_Microphone.py
index fa8e5c3..af7e52c 100644
--- a/client/site_tests/audiovideo_Microphone/audiovideo_Microphone.py
+++ b/client/site_tests/audiovideo_Microphone/audiovideo_Microphone.py
@@ -2,10 +2,11 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import os, time, utils
+import logging, os, tempfile, time, utils
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
+from autotest_lib.client.cros.audio import audio_helper
DURATION = 30
BYTES_PER_SAMPLE = 2
@@ -14,38 +15,42 @@
class audiovideo_Microphone(test.test):
version = 1
- def verify_capture(self, ch, rate):
- file_name = "/tmp/%s-%s.capture" % (ch, rate)
- cmd = "rm -f %s" % file_name
- utils.system(cmd, ignore_status=True)
- cmd = "arecord -f dat -D default -c %s -r %s -d %d %s"
- cmd = cmd % (ch, rate, DURATION, file_name)
- utils.system(cmd)
- size = os.path.getsize(file_name)
- if (size < DURATION * rate * ch * BYTES_PER_SAMPLE * TOLERATE) :
- raise error.TestFail("File size not correct: %s" % file_name)
- utils.system("rm -f %s" % file_name)
+ def verify_capture(self, sndcard, ch, rate):
+ cmd = "arecord -D plughw:%s -f dat -c %s -r %s -d %d %s"
+ recorded_file = tempfile.NamedTemporaryFile(mode='w+t').name
+ try:
+ utils.system(cmd % (sndcard, ch, rate, DURATION, recorded_file))
+ size = os.path.getsize(recorded_file)
+ if (size < DURATION * rate * ch * BYTES_PER_SAMPLE * TOLERATE) :
+ raise error.TestFail("File size not correct: %d" % size)
+ finally:
+ os.remove(recorded_file)
def run_once(self):
cpuType = utils.get_cpu_arch()
+
+ sndcard = audio_helper.find_hw_soundcard_name(cpuType)
+ if sndcard is None:
+ raise error.TestError('No sound card detected')
+
# Microphone should be on by default.
if cpuType != "arm":
- cmd = 'amixer -c 0 cget name="Capture Switch" | grep values=on,on'
- output = utils.system_output(cmd)
+ cmd = 'amixer -D hw:%s cget name="Capture Switch" | grep values=on,on'
+ output = utils.system_output(cmd % sndcard)
if (output == ''):
raise error.TestFail('The microphone is not on by default.')
else:
# TODO(jiesun): find consistent way to find the ALSA mixer control
# names for both internal mic and external mic on ARM, which is
# independent of the audio codec hardware vendor.
- print "Warning: Can not verify the microphone capture switch."
+ logging.warning("Can not verify the microphone capture switch.")
# Mono and stereo capturing should work fine @ 44.1KHz and 48KHz.
- self.verify_capture(1, 44100)
- self.verify_capture(1, 48000)
- self.verify_capture(2, 48000)
- self.verify_capture(2, 44100)
+ self.verify_capture(sndcard, 1, 44100)
+ self.verify_capture(sndcard, 1, 48000)
+ self.verify_capture(sndcard, 2, 48000)
+ self.verify_capture(sndcard, 2, 44100)
# TODO(zhurunz):
# Low latency capturing should work fine with low CPU usage.