1# Copyright 2014 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"""Audio port ids shared in Chameleon audio test framework"""
5
6
7class ChameleonIds(object):
8    """Ids for audio ports on Chameleon
9
10    An Id is composed by host name 'Chameleon' and interface name e.g. 'HDMI'.
11    Note that the interface name must match what get_connector_type method
12    returns on a ChameleonPort so ChameleonPortFinder can find the port.
13
14    """
15    HDMI = 'Chameleon HDMI'
16    LINEIN = 'Chameleon LineIn'
17    LINEOUT = 'Chameleon LineOut'
18    MIC = 'Chameleon Mic'
19    USBIN = 'Chameleon USBIn'
20    USBOUT = 'Chameleon USBOut'
21
22    SINK_PORTS = [HDMI, LINEIN, MIC, USBIN]
23    SOURCE_PORTS = [LINEOUT, USBOUT]
24
25
26class CrosIds(object):
27    """Ids for audio ports on Cros device.
28
29    Note that an bidirectional interface like 3.5mm jack is separated to
30    two interfaces, that is, 'Headphone' and 'External Mic'.
31
32    """
33    HDMI = 'Cros HDMI'
34    HEADPHONE = 'Cros Headphone'
35    EXTERNAL_MIC = 'Cros External Mic'
36    SPEAKER = 'Cros Speaker'
37    INTERNAL_MIC = 'Cros Internal Mic'
38    BLUETOOTH_HEADPHONE = 'Cros Bluetooth Headphone'
39    BLUETOOTH_MIC = 'Cros Bluetooth Mic'
40    USBIN = 'Cros USBIn'
41    USBOUT = 'Cros USBOut'
42
43    SINK_PORTS = [EXTERNAL_MIC, INTERNAL_MIC, BLUETOOTH_MIC, USBIN]
44    SOURCE_PORTS = [HDMI, HEADPHONE, SPEAKER, BLUETOOTH_HEADPHONE, USBOUT]
45
46
47class PeripheralIds(object):
48    """Ids for peripherals.
49
50    These peripherals will be accessible by Cros device/Chameleon through
51    audio board.
52
53    """
54    SPEAKER = 'Peripheral Speaker'
55    MIC = 'Peripheral Mic'
56
57    # Peripheral devices should have two roles but we only care one.
58    # For example, to test internal microphone on Cros device:
59    #
60    #                                         (air)
61    #                    Peripheral Speaker -------> Internal Microphone
62    #                         ------                  ------
63    # Chameleon LineOut ----> |    |                  |    |
64    #                         ------                  ------
65    #                        Audio board             Cros device
66    #
67    # In the above example, peripheral speaker is a sink as it takes signal
68    # from audio board. It should be a source as peripheral speaker transfer
69    # signal to internal microphone of Cros device,
70    # However, we do not abstract air as a link because it does not contain
71    # properties like level, channel_map, occupied to manipulate.
72    # So, we set peripheral speaker to be a sink to reflect the part related
73    # to audio bus.
74    #
75    # For example, to test internal speaker on Cros device:
76    #
77    #                                         (air)
78    #                    Peripheral Micropone <----- Internal Speaker
79    #                         ------                  ------
80    # Chameleon LineIn <----  |    |                  |    |
81    #                         ------                  ------
82    #                        Audio board             Cros device
83    #
84    # In the above example, peripheral microphone is a source as it feeds signal
85    # to audio board. It should be a sink as peripheral microphone receives
86    # signal from internal speaker of Cros device.
87    # However, we do not abstract air as a link because it does not contain
88    # properties like level, channel_map, occupied to manipulate.
89    # So, we set peripheral microphone to be a source to reflect the part related
90    # to audio bus.
91
92    BLUETOOTH_DATA_RX = ('Peripheral Bluetooth Signal Output and Data Receiver')
93    BLUETOOTH_DATA_TX = ('Peripheral Bluetooth Signal Input and Data '
94                         'Transmitter')
95
96    # Bluetooth module has both source and sink roles.
97    # When Cros device plays audio to bluetooth module data receiver through
98    # bluetooth connection, bluetooth module is a sink of audio signal.
99    # When we route audio signal from bluetooth signal output to Chameleon
100    # Line-In, bluetooth module is a signal source in terms of audio bus.
101    #
102    #                     Bluetooth module
103    #
104    #                    signal     data      (bluetooth)
105    #                    output    receiver <------------ Bluetooth Headphone
106    #                         ------                        ------
107    # Chameleon LineIn <----  |    |                        |    |
108    #                         ------                        ------
109    #                        Audio board                   Cros device
110    #
111    #
112    # When Cros device records audio from bluetooth module data transmitter
113    # through bluetooth connection, bluetooth module is a source of audio
114    # signal. When we route audio signal from Chameleon Line-Out to bluetooth
115    # signal input, bluetooth module is a signal sink in terms of audio bus.
116    #
117    #                     Bluetooth module
118    #
119    #                    signal     data      (bluetooth)
120    #                    input    transmitter -----------> Bluetooth Microphone
121    #                         ------                        ------
122    # Chameleon LineOut ----> |    |                        |    |
123    #                         ------                        ------
124    #                        Audio board                   Cros device
125    #
126    # From above diagram it is clear that "signal output" is connected to
127    # "data receiver", while "signal input" is connected to "data transmitter".
128    # To simplify the number of nodes, we group "signal output" and
129    # "data receiver" into one Id, and group "signal input" and
130    # "data transmitter" into one Id. Also, we let these two Ids be both source
131    # and sink.
132    SOURCE_PORTS = [MIC, BLUETOOTH_DATA_RX, BLUETOOTH_DATA_TX]
133    SINK_PORTS = [SPEAKER, BLUETOOTH_DATA_RX, BLUETOOTH_DATA_TX]
134
135
136SINK_PORTS = []
137for cls in [ChameleonIds, CrosIds, PeripheralIds]:
138    SINK_PORTS += cls.SINK_PORTS
139
140SOURCE_PORTS = []
141for cls in [ChameleonIds, CrosIds, PeripheralIds]:
142    SOURCE_PORTS += cls.SOURCE_PORTS
143
144
145def get_host(port_id):
146    """Parses given port_id to get host name.
147
148    @param port_id: A string, that is, id in ChameleonIds, CrosIds, or
149                    PeripheralIds.
150
151    @returns: Host name. A string in ['Chameleon', 'Cros', 'Peripheral'].
152
153    @raises: ValueError if port_id is invalid.
154
155    """
156    host = port_id.split()[0]
157    if host not in ['Chameleon', 'Cros', 'Peripheral']:
158        raise ValueError('Not a valid port id: %r' % port_id)
159    return host
160
161
162def get_interface(port_id):
163    """Parses given port_id to get interface name.
164
165    @param port_id: A string, that is, id in ChameleonIds, CrosIds, or
166                    PeripheralIds.
167
168    @returns: Interface name. A string, e.g. 'HDMI', 'LineIn'.
169
170    @raises: ValueError if port_id is invalid.
171
172    """
173    try:
174        return port_id.split(' ', 1)[1]
175    except IndexError:
176        raise ValueError('Not a valid port id: %r' % port_id)
177
178
179def get_role(port_id):
180    """Gets the role of given port_id.
181
182    @param port_id: A string, that is, id in ChameleonIds, CrosIds, or
183                    PeripheralIds.
184
185    @returns: 'source' or 'sink'.
186
187    @raises: ValueError if port_id is invalid.
188
189    """
190    if port_id in SOURCE_PORTS:
191        return 'source'
192    if port_id in SINK_PORTS:
193        return 'sink'
194    if port_id in SOURCE_PORTS and port_id in SINK_PORTS:
195        return 'sink | source'
196    raise ValueError('Not a valid port id: %r' % port_id)
197