chameleon: XMLRPC: update the USB audio flow.
To support analog audio tests, the Raspberry Pi will use an external sound card to send/receive analog signal from 3.5mm headphone/mic port.
The XMLRPC service should detect the existance of the external sound card and choose the correct USB audio node.
BUG=b:281641828
TEST=tested locally with AudioBasicHeadphone and
AudioBasicExternalMicrophone
Change-Id: I5a3dbe9ca6fe91b505455b5ea72686e9d291382b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/chameleon/+/4530159
Reviewed-by: Kalin Stoyanov <kalin@chromium.org>
Commit-Queue: YJ Lee <yunjunlee@chromium.org>
Tested-by: YJ Lee <yunjunlee@chromium.org>
Reviewed-by: Yu-Hsuan Hsu <yuhsuan@chromium.org>
diff --git a/chameleond/devices/usb_audio_flow.py b/chameleond/devices/usb_audio_flow.py
index 8d282c8..bbc4201 100644
--- a/chameleond/devices/usb_audio_flow.py
+++ b/chameleond/devices/usb_audio_flow.py
@@ -10,6 +10,8 @@
import logging
import os
+import re
+import subprocess
import tempfile
from . import chameleon_common # pylint: disable=W0611, C0411
@@ -127,7 +129,41 @@
"""
pass
- def _GetAlsaUtilCommandArgs(self, data_format):
+ def _GetUSBAudioDevice(self, alsa_command):
+ """Returns the correct audio device.
+
+ In the Raspberry Pi Analog Audio testbed, an external USB sound card is
+ attached to Pi handle analog audio to/from DUT.
+
+ Check the existence of the external USB sound card, and return the correct
+ audio device if exist.
+
+ Args:
+ alsa_command: ALSA command, accepts only 'aplay' and 'arecord'.
+
+ Returns:
+ A string with the following format - "hw:x,0", and x is the device number
+ with default value of UAC2.
+ """
+ logging.info("Checking the existence of external USB sound card...")
+ if alsa_command not in ['aplay', 'arecord']:
+ err_msg = 'Unable to pick PCM - unexpected ALSA command:' + alsa_command
+ raise USBAudioFlowError(err_msg)
+
+ output = subprocess.check_output([alsa_command,'-l']).decode('utf-8')
+
+ # use regex to find the device number
+ ext_card = re.search("([\d]): ICUSBAUDIO7D", output)
+ if ext_card:
+ return 'hw:' + ext_card[1] + ',0'
+ uac2_gadget = re.search("([\d]): UAC2Gadget", output)
+ if uac2_gadget:
+ return 'hw:' + uac2_gadget[1] + ',0'
+ else:
+ err_msg = 'Unable to pick PCM from existing audio devices:' + output
+ raise USBAudioFlowError(err_msg)
+
+ def _GetAlsaUtilCommandArgs(self, data_format, device_name):
"""Returns a list of parameter flags paired with corresponding arguments.
The argument values are taken from data_format.
@@ -135,11 +171,13 @@
Args:
data_format: An AudioDataFormat object whose values are passed as
arguments into the Alsa util command.
+ device_name: ALSA device name
Returns:
A list containing argument strings
"""
- params_list = ['-D', 'hw:0,0',
+ logging.info("Using audio device: %s", device_name)
+ params_list = ['-D', device_name,
'-t', data_format.file_type,
'-f', data_format.sample_format,
'-c', str(data_format.channel),
@@ -236,7 +274,8 @@
raise USBAudioFlowError('USB Audio only supports save to file')
self._supported_data_format = self._usb_ctrl.GetSupportedCaptureDataFormat()
self._supported_data_format.file_type = self._captured_file_type
- params_list = self._GetAlsaUtilCommandArgs(self._supported_data_format)
+ device_name = self._GetUSBAudioDevice('arecord')
+ params_list = self._GetAlsaUtilCommandArgs(self._supported_data_format, device_name)
file_suffix = '.' + self._captured_file_type
recorded_file = tempfile.NamedTemporaryFile(prefix='audio_',
suffix=file_suffix,
@@ -349,7 +388,8 @@
self._usb_ctrl.GetSupportedPlaybackDataFormat()
if self._InputDataFormatIsCompatible(data_format):
data_format_object = audio.CreateAudioDataFormatFromDict(data_format)
- params_list = self._GetAlsaUtilCommandArgs(data_format_object)
+ device_name = self._GetUSBAudioDevice('aplay')
+ params_list = self._GetAlsaUtilCommandArgs(data_format_object, device_name)
params_list.append(path)
self._subprocess = system_tools.SystemTools.RunInSubprocess('aplay',
*params_list)