xref: /aosp_15_r20/external/autotest/client/cros/audio/audio_spec.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Copyright 2017 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"""This module provides the test utilities for audio spec."""
5
6import collections
7
8_BOARD_TYPE_CHROMEBOX = 'CHROMEBOX'
9_BOARD_TYPE_CHROMEBIT = 'CHROMEBIT'
10_BOARD_WITHOUT_SOUND_CARD = ['gale', 'veyron_rialto']
11
12
13def has_internal_speaker(board_type, board_name):
14    """Checks if a board has internal speaker.
15
16    @param board_type: board type string. E.g. CHROMEBOX, CHROMEBIT, and etc.
17    @param board_name: board name string.
18
19    @returns: True if the board has internal speaker. False otherwise.
20
21    """
22    board_name = strip_kernelnext_suffix(board_name)
23    if (board_type == _BOARD_TYPE_CHROMEBOX
24                or board_type == _BOARD_TYPE_CHROMEBIT
25                or board_name in _BOARD_WITHOUT_SOUND_CARD):
26        return False
27    return True
28
29
30def has_internal_microphone(board_type):
31    """Checks if a board has internal microphone.
32
33    @param board_type: board type string. E.g. CHROMEBOX, CHROMEBIT, and etc.
34
35    @returns: True if the board has internal microphone. False otherwise.
36
37    """
38    if (board_type == _BOARD_TYPE_CHROMEBOX
39                or board_type == _BOARD_TYPE_CHROMEBIT):
40        return False
41    return True
42
43
44def has_audio_jack(board_name, board_type):
45    """Checks if a board has a 3.5mm audio jack.
46
47    @param board_name: board name of the DUT.
48    @param board_type: board type string. E.g. CHROMEBOX, CHROMEBIT, and etc.
49
50    @returns: True if the board has headphone. False otherwise.
51
52    """
53    board_name = strip_kernelnext_suffix(board_name)
54    if (board_name in ['nocturne'] or board_type == _BOARD_TYPE_CHROMEBIT):
55        return False
56    return True
57
58def strip_kernelnext_suffix(board_name):
59    """Removes the '-kernelnext' suffix from board_name if present.
60
61    @param board_name: board name of the DUT.
62
63    @returns: board_name without '-kernelnext' suffix.
64
65    """
66    if board_name.endswith("-kernelnext"):
67        return board_name[:-len("-kernelnext")]
68
69    return board_name
70
71BOARDS_WITH_HOTWORDING = [
72        'atlas', 'coral', 'eve', 'kevin', 'nami', 'nocturne', 'rammus',
73        'samus', 'volteer'
74]
75
76
77def has_hotwording(board_name, model_name):
78    """Checks if a board has hotwording.
79
80    @param board_name: board name of the DUT.
81    @param model_name: model name of the DUT.
82
83    @returns: True if the board has hotwording.
84
85    """
86    board_name = strip_kernelnext_suffix(board_name)
87    return (board_name in BOARDS_WITH_HOTWORDING)
88
89def has_echo_reference(board_name):
90    """Checks if a board has echo reference.
91
92    @param board_name: board name of the DUT.
93
94    @returns: True if the board has echo reference.
95
96    """
97    board_name = strip_kernelnext_suffix(board_name)
98    return board_name in ['nocturne', 'atlas', 'volteer']
99
100
101BoardInfo = collections.namedtuple('BoardInfo', ['board', 'model', 'sku'])
102
103BOARDS_WITH_FOUR_INTERNAL_SPEAKERS = [
104        BoardInfo('strongbad', 'homestar', ''),
105]
106
107BOARDS_WITH_TWO_INTERNAL_MICS = [
108        BoardInfo('coral', 'babytiger', ''),
109        BoardInfo('coral', 'nasher360', ''),
110        BoardInfo('coral', 'rabbid', ''),
111        BoardInfo('coral', 'robo360', ''),
112        BoardInfo('dedede', 'boten', ''),
113        BoardInfo('grunt', 'treeya360', '175'),
114        BoardInfo('hatch', 'kohaku', ''),
115        BoardInfo('octopus', 'ampton', ''),
116        BoardInfo('octopus', 'bobba360', '9'),
117        BoardInfo('octopus', 'bobba360', '10'),
118        BoardInfo('octopus', 'dood', ''),
119        BoardInfo('octopus', 'foob360', ''),
120        BoardInfo('octopus', 'grabbiter', ''),
121        BoardInfo('octopus', 'phaser360', '3'),
122        BoardInfo('octopus', 'sparky', ''),
123        BoardInfo('octopus', 'sparky360', ''),
124        BoardInfo('octopus', 'vortininja', ''),
125        BoardInfo('snappy', 'snappy', '8'),
126        BoardInfo('zork', 'dalboz', ''),
127        BoardInfo('zork', 'ezkinil', ''),
128        # b/232791346 clarifies zork-morpheus SKU 1510014998
129        # has a a front mic ONLY. Other SKUs have both UFC and WFC
130        # for which the following line will be valid.
131        #BoardInfo('zork', 'morphius', ''),
132        BoardInfo('zork', 'vilboz360', '1518534658'),
133        BoardInfo('zork', 'vilboz360', '1518534660'),
134        BoardInfo('zork', 'vilboz360', '1518534661'),
135        BoardInfo('zork', 'vilboz360', '1518534662'),
136        BoardInfo('keeby', 'lalala', ''),
137        BoardInfo('dedede', 'drawcia', ''),
138]
139
140
141def get_internal_speaker_channel_count(board_type, board, model, sku):
142    """Gets the channel count of internal speakers.
143    @param board_type: board type string. E.g. CHROMEBOX, CHROMEBIT, and etc.
144    @param board: board name of the DUT.
145    @param model: model name of the DUT.
146    @param sku: sku number string of the DUT.
147
148    @returns: The channel count of internal speakers.
149
150    """
151    if not has_internal_speaker(board_type, board):
152        return 0
153
154    for b in BOARDS_WITH_FOUR_INTERNAL_SPEAKERS:
155        if b.board == board and b.model == model:
156            if b.sku == '' or b.sku == sku:
157                return 4
158    return 2
159
160
161def get_num_internal_microphone(board_type, board, model, sku):
162    """Gets the number of internal microphones.
163
164    @param board_type: board type string. E.g. CHROMEBOX, CHROMEBIT, and etc.
165    @param board: board name of the DUT.
166    @param model: model name of the DUT.
167    @param sku: sku number string of the DUT.
168
169    @returns: The number of internal microphones.
170
171    """
172    if not has_internal_microphone(board_type):
173        return 0
174
175    board = strip_kernelnext_suffix(board)
176    for b in BOARDS_WITH_TWO_INTERNAL_MICS:
177        if b.board == board and b.model == model:
178            if b.sku == '' or b.sku == sku:
179                return 2
180
181    return 1
182
183
184INTERNAL_MIC_NODE = {
185        ('nami', 'pantheon'): 'FRONT_MIC',
186        ('nami', 'sona'): 'FRONT_MIC',
187        ('nami', 'syndra'): 'FRONT_MIC',
188        ('nami', 'vayne'): 'FRONT_MIC',
189}
190
191
192def get_internal_mic_node(board_type, board, model, sku):
193    """Return the expected internal microphone node for given board name and
194       model name.
195
196    @param board_type: board type string. E.g. CHROMEBOX, CHROMEBIT, and etc.
197    @param board: board name of the DUT.
198    @param model: model name of the DUT.
199    @param sku: sku number string of the DUT.
200
201    @returns: The name of the expected internal microphone nodes.
202    """
203    board = strip_kernelnext_suffix(board)
204    if get_num_internal_microphone(board_type, board, model, sku) == 2:
205        return 'FRONT_MIC'
206
207    return INTERNAL_MIC_NODE.get((board, model), 'INTERNAL_MIC')
208
209
210INTERNAL_MIC_NODES = {
211        ('nami', 'vayne'): ['FRONT_MIC'],
212}
213
214
215def get_plugged_internal_mics(board_type, board, model, sku):
216    """Return a list of all the plugged internal microphone nodes for given
217       board name and model name.
218
219    @param board_type: board type string. E.g. CHROMEBOX, CHROMEBIT, and etc.
220    @param board: board name of the DUT.
221    @param model: model name of the DUT.
222    @param sku: sku number string of the DUT.
223
224    @returns: A list of all the plugged internal microphone nodes.
225    """
226    board = strip_kernelnext_suffix(board)
227    if get_num_internal_microphone(board_type, board, model, sku) == 2:
228        return ['FRONT_MIC', 'REAR_MIC']
229
230    return INTERNAL_MIC_NODES.get((board, model), ['INTERNAL_MIC'])
231
232
233HEADPHONE_NODE = {
234        ('sarien'): 'LINEOUT',
235        ('drallion'): 'LINEOUT',
236}
237
238
239def get_headphone_node(board):
240    """Return the expected headphone node for given board name.
241
242    @param board: board name of the DUT.
243
244    @returns: The name of the expected headphone node.
245    """
246    board = strip_kernelnext_suffix(board)
247    return HEADPHONE_NODE.get((board), 'HEADPHONE')
248