# Copyright 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Audio port ids shared in Chameleon audio test framework"""
class ChameleonIds(object):
"""Ids for audio ports on Chameleon
An Id is composed by host name 'Chameleon' and interface name e.g. 'HDMI'.
Note that the interface name must match what get_connector_type method
returns on a ChameleonPort so ChameleonPortFinder can find the port.
"""
HDMI = 'Chameleon HDMI'
LINEIN = 'Chameleon LineIn'
LINEOUT = 'Chameleon LineOut'
MIC = 'Chameleon Mic'
USBIN = 'Chameleon USBIn'
USBOUT = 'Chameleon USBOut'
SINK_PORTS = [HDMI, LINEIN, MIC, USBIN]
SOURCE_PORTS = [LINEOUT, USBOUT]
class CrosIds(object):
"""Ids for audio ports on Cros device.
Note that an bidirectional interface like 3.5mm jack is separated to
two interfaces, that is, 'Headphone' and 'External Mic'.
"""
HDMI = 'Cros HDMI'
HEADPHONE = 'Cros Headphone'
EXTERNAL_MIC = 'Cros External Mic'
SPEAKER = 'Cros Speaker'
INTERNAL_MIC = 'Cros Internal Mic'
BLUETOOTH_HEADPHONE = 'Cros Bluetooth Headphone'
BLUETOOTH_MIC = 'Cros Bluetooth Mic'
USBIN = 'Cros USBIn'
USBOUT = 'Cros USBOut'
SINK_PORTS = [EXTERNAL_MIC, INTERNAL_MIC, BLUETOOTH_MIC, USBIN]
SOURCE_PORTS = [HDMI, HEADPHONE, SPEAKER, BLUETOOTH_HEADPHONE, USBOUT]
class PeripheralIds(object):
"""Ids for peripherals.
These peripherals will be accessible by Cros device/Chameleon through
audio board.
"""
SPEAKER = 'Peripheral Speaker'
MIC = 'Peripheral Mic'
# Peripheral devices should have two roles but we only care one.
# For example, to test internal microphone on Cros device:
#
# (air)
# Peripheral Speaker -------> Internal Microphone
# ------ ------
# Chameleon LineOut ----> | | | |
# ------ ------
# Audio board Cros device
#
# In the above example, peripheral speaker is a sink as it takes signal
# from audio board. It should be a source as peripheral speaker transfer
# signal to internal microphone of Cros device,
# However, we do not abstract air as a link because it does not contain
# properties like level, channel_map, occupied to manipulate.
# So, we set peripheral speaker to be a sink to reflect the part related
# to audio bus.
#
# For example, to test internal speaker on Cros device:
#
# (air)
# Peripheral Micropone <----- Internal Speaker
# ------ ------
# Chameleon LineIn <---- | | | |
# ------ ------
# Audio board Cros device
#
# In the above example, peripheral microphone is a source as it feeds signal
# to audio board. It should be a sink as peripheral microphone receives
# signal from internal speaker of Cros device.
# However, we do not abstract air as a link because it does not contain
# properties like level, channel_map, occupied to manipulate.
# So, we set peripheral microphone to be a source to reflect the part related
# to audio bus.
BLUETOOTH_DATA_RX = ('Peripheral Bluetooth Signal Output and Data Receiver')
BLUETOOTH_DATA_TX = ('Peripheral Bluetooth Signal Input and Data '
'Transmitter')
# Bluetooth module has both source and sink roles.
# When Cros device plays audio to bluetooth module data receiver through
# bluetooth connection, bluetooth module is a sink of audio signal.
# When we route audio signal from bluetooth signal output to Chameleon
# Line-In, bluetooth module is a signal source in terms of audio bus.
#
# Bluetooth module
#
# signal data (bluetooth)
# output receiver <------------ Bluetooth Headphone
# ------ ------
# Chameleon LineIn <---- | | | |
# ------ ------
# Audio board Cros device
#
#
# When Cros device records audio from bluetooth module data transmitter
# through bluetooth connection, bluetooth module is a source of audio
# signal. When we route audio signal from Chameleon Line-Out to bluetooth
# signal input, bluetooth module is a signal sink in terms of audio bus.
#
# Bluetooth module
#
# signal data (bluetooth)
# input transmitter -----------> Bluetooth Microphone
# ------ ------
# Chameleon LineOut ----> | | | |
# ------ ------
# Audio board Cros device
#
# From above diagram it is clear that "signal output" is connected to
# "data receiver", while "signal input" is connected to "data transmitter".
# To simplify the number of nodes, we group "signal output" and
# "data receiver" into one Id, and group "signal input" and
# "data transmitter" into one Id. Also, we let these two Ids be both source
# and sink.
SOURCE_PORTS = [MIC, BLUETOOTH_DATA_RX, BLUETOOTH_DATA_TX]
SINK_PORTS = [SPEAKER, BLUETOOTH_DATA_RX, BLUETOOTH_DATA_TX]
SINK_PORTS = []
for cls in [ChameleonIds, CrosIds, PeripheralIds]:
SINK_PORTS += cls.SINK_PORTS
SOURCE_PORTS = []
for cls in [ChameleonIds, CrosIds, PeripheralIds]:
SOURCE_PORTS += cls.SOURCE_PORTS
def get_host(port_id):
"""Parses given port_id to get host name.
@param port_id: A string, that is, id in ChameleonIds, CrosIds, or
PeripheralIds.
@returns: Host name. A string in ['Chameleon', 'Cros', 'Peripheral'].
@raises: ValueError if port_id is invalid.
"""
host = port_id.split()[0]
if host not in ['Chameleon', 'Cros', 'Peripheral']:
raise ValueError('Not a valid port id: %r' % port_id)
return host
def get_interface(port_id):
"""Parses given port_id to get interface name.
@param port_id: A string, that is, id in ChameleonIds, CrosIds, or
PeripheralIds.
@returns: Interface name. A string, e.g. 'HDMI', 'LineIn'.
@raises: ValueError if port_id is invalid.
"""
try:
return port_id.split(' ', 1)[1]
except IndexError:
raise ValueError('Not a valid port id: %r' % port_id)
def get_role(port_id):
"""Gets the role of given port_id.
@param port_id: A string, that is, id in ChameleonIds, CrosIds, or
PeripheralIds.
@returns: 'source' or 'sink'.
@raises: ValueError if port_id is invalid.
"""
if port_id in SOURCE_PORTS:
return 'source'
if port_id in SINK_PORTS:
return 'sink'
if port_id in SOURCE_PORTS and port_id in SINK_PORTS:
return 'sink | source'
raise ValueError('Not a valid port id: %r' % port_id)