blob: 8de8a376f493c941e86401be4581f57dfb1c7978 [file] [log] [blame]
Owen Linca365f82013-11-08 16:52:28 +08001# Copyright (c) 2013 The Chromium 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
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +08005"""This module provides cras audio utilities."""
6
Owen Linca365f82013-11-08 16:52:28 +08007import logging
8import re
9
Owen Lin9d19b272013-11-28 12:13:24 +080010from autotest_lib.client.cros.audio import cmd_utils
Owen Linca365f82013-11-08 16:52:28 +080011
12_CRAS_TEST_CLIENT = '/usr/bin/cras_test_client'
Owen Linca365f82013-11-08 16:52:28 +080013
Cheng-Yi Chiang08c25492015-11-06 15:15:49 +080014
15class CrasUtilsError(Exception):
16 pass
17
18
Owen Linca365f82013-11-08 16:52:28 +080019def playback(*args, **kargs):
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080020 """A helper function to execute the playback_cmd.
21
22 @param args: args passed to playback_cmd.
23 @param kargs: kargs passed to playback_cmd.
24
25 """
Owen Lin9d19b272013-11-28 12:13:24 +080026 cmd_utils.execute(playback_cmd(*args, **kargs))
Owen Linca365f82013-11-08 16:52:28 +080027
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +080028
Owen Linca365f82013-11-08 16:52:28 +080029def capture(*args, **kargs):
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080030 """A helper function to execute the capture_cmd.
31
32 @param args: args passed to capture_cmd.
33 @param kargs: kargs passed to capture_cmd.
34
35 """
Owen Lin9d19b272013-11-28 12:13:24 +080036 cmd_utils.execute(capture_cmd(*args, **kargs))
Owen Linca365f82013-11-08 16:52:28 +080037
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +080038
Owen Lin2f7e7f42013-12-25 17:25:43 +080039def playback_cmd(playback_file, block_size=None, duration=None,
Owen Lin2013e462013-12-05 17:54:42 +080040 channels=2, rate=48000):
Owen Linca365f82013-11-08 16:52:28 +080041 """Gets a command to playback a file with given settings.
42
43 @param playback_file: the name of the file to play. '-' indicates to
44 playback raw audio from the stdin.
Owen Lin2f7e7f42013-12-25 17:25:43 +080045 @param block_size: the number of frames per callback(dictates latency).
Owen Linca365f82013-11-08 16:52:28 +080046 @param duration: seconds to playback
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080047 @param channels: number of channels.
Owen Linca365f82013-11-08 16:52:28 +080048 @param rate: the sampling rate
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +080049
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080050 @returns: The command args put in a list of strings.
51
Owen Linca365f82013-11-08 16:52:28 +080052 """
53 args = [_CRAS_TEST_CLIENT]
54 args += ['--playback_file', playback_file]
Owen Lin2f7e7f42013-12-25 17:25:43 +080055 if block_size is not None:
56 args += ['--block_size', str(block_size)]
Owen Linca365f82013-11-08 16:52:28 +080057 if duration is not None:
58 args += ['--duration', str(duration)]
Owen Lin2013e462013-12-05 17:54:42 +080059 args += ['--num_channels', str(channels)]
Owen Linca365f82013-11-08 16:52:28 +080060 args += ['--rate', str(rate)]
61 return args
62
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +080063
Owen Lina8129c62013-11-26 16:51:46 +080064def capture_cmd(
Owen Lin2f7e7f42013-12-25 17:25:43 +080065 capture_file, block_size=None, duration=10, channels=1, rate=48000):
Owen Linca365f82013-11-08 16:52:28 +080066 """Gets a command to capture the audio into the file with given settings.
67
68 @param capture_file: the name of file the audio to be stored in.
Owen Lin2f7e7f42013-12-25 17:25:43 +080069 @param block_size: the number of frames per callback(dictates latency).
Cheng-Yi Chiangeaf53292015-01-12 20:53:56 +080070 @param duration: seconds to record. If it is None, duration is not set,
71 and command will keep capturing audio until it is
72 terminated.
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080073 @param channels: number of channels.
Owen Linca365f82013-11-08 16:52:28 +080074 @param rate: the sampling rate.
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +080075
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080076 @returns: The command args put in a list of strings.
77
Owen Linca365f82013-11-08 16:52:28 +080078 """
79 args = [_CRAS_TEST_CLIENT]
80 args += ['--capture_file', capture_file]
Owen Lin2f7e7f42013-12-25 17:25:43 +080081 if block_size is not None:
82 args += ['--block_size', str(block_size)]
Cheng-Yi Chiangeaf53292015-01-12 20:53:56 +080083 if duration is not None:
84 args += ['--duration', str(duration)]
Owen Lina8129c62013-11-26 16:51:46 +080085 args += ['--num_channels', str(channels)]
Owen Linca365f82013-11-08 16:52:28 +080086 args += ['--rate', str(rate)]
87 return args
88
Owen Lindae7a0d2013-12-05 13:34:06 +080089
90def loopback(*args, **kargs):
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080091 """A helper function to execute loopback_cmd.
92
93 @param args: args passed to loopback_cmd.
94 @param kargs: kargs passed to loopback_cmd.
95
96 """
97
Owen Lindae7a0d2013-12-05 13:34:06 +080098 cmd_utils.execute(loopback_cmd(*args, **kargs))
99
100
Owen Lin2013e462013-12-05 17:54:42 +0800101def loopback_cmd(output_file, duration=10, channels=2, rate=48000):
Owen Lindae7a0d2013-12-05 13:34:06 +0800102 """Gets a command to record the loopback.
103
104 @param output_file: The name of the file the loopback to be stored in.
105 @param channels: The number of channels of the recorded audio.
106 @param duration: seconds to record.
107 @param rate: the sampling rate.
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800108
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +0800109 @returns: The command args put in a list of strings.
110
Owen Lindae7a0d2013-12-05 13:34:06 +0800111 """
112 args = [_CRAS_TEST_CLIENT]
113 args += ['--loopback_file', output_file]
114 args += ['--duration_seconds', str(duration)]
115 args += ['--num_channels', str(channels)]
116 args += ['--rate', str(rate)]
117 return args
118
119
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800120def get_cras_nodes_cmd():
121 """Gets a command to query the nodes from Cras.
122
123 @returns: The command to query nodes information from Cras using dbus-send.
124
125 """
126 return ('dbus-send --system --type=method_call --print-reply '
127 '--dest=org.chromium.cras /org/chromium/cras '
128 'org.chromium.cras.Control.GetNodes')
129
130
Owen Linca365f82013-11-08 16:52:28 +0800131def set_system_volume(volume):
132 """Set the system volume.
133
134 @param volume: the system output vlume to be set(0 - 100).
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800135
Owen Linca365f82013-11-08 16:52:28 +0800136 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800137 get_cras_control_interface().SetOutputVolume(volume)
Owen Linca365f82013-11-08 16:52:28 +0800138
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800139
Owen Linca365f82013-11-08 16:52:28 +0800140def set_node_volume(node_id, volume):
141 """Set the volume of the given output node.
142
143 @param node_id: the id of the output node to be set the volume.
144 @param volume: the volume to be set(0-100).
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800145
Owen Linca365f82013-11-08 16:52:28 +0800146 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800147 get_cras_control_interface().SetOutputNodeVolume(node_id, volume)
Owen Linca365f82013-11-08 16:52:28 +0800148
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800149
Owen Linca365f82013-11-08 16:52:28 +0800150def set_capture_gain(gain):
151 """Set the system capture gain.
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800152
Owen Linca365f82013-11-08 16:52:28 +0800153 @param gain the capture gain in db*100 (100 = 1dB)
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800154
Owen Linca365f82013-11-08 16:52:28 +0800155 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800156 get_cras_control_interface().SetInputGain(gain)
Owen Linca365f82013-11-08 16:52:28 +0800157
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800158
Cheng-Yi Chiang3dd376d2015-10-20 16:28:21 +0800159def get_cras_control_interface(private=False):
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800160 """Gets Cras DBus control interface.
161
Cheng-Yi Chiang3dd376d2015-10-20 16:28:21 +0800162 @param private: Set to True to use a new instance for dbus.SystemBus
163 instead of the shared instance.
164
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800165 @returns: A dBus.Interface object with Cras Control interface.
166
167 @raises: ImportError if this is not called on Cros device.
168
169 """
170 try:
171 import dbus
172 except ImportError, e:
173 logging.exception(
174 'Can not import dbus: %s. This method should only be '
175 'called on Cros device.', e)
176 raise
Cheng-Yi Chiang3dd376d2015-10-20 16:28:21 +0800177 bus = dbus.SystemBus(private=private)
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800178 cras_object = bus.get_object('org.chromium.cras', '/org/chromium/cras')
179 return dbus.Interface(cras_object, 'org.chromium.cras.Control')
180
181
182def get_cras_nodes():
183 """Gets nodes information from Cras.
184
185 @returns: A dict containing information of each node.
186
187 """
188 return get_cras_control_interface().GetNodes()
Owen Linca365f82013-11-08 16:52:28 +0800189
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800190
Owen Linca365f82013-11-08 16:52:28 +0800191def get_selected_nodes():
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800192 """Gets selected output nodes and input nodes.
Owen Linca365f82013-11-08 16:52:28 +0800193
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800194 @returns: A tuple (output_nodes, input_nodes) where each
195 field is a list of selected node IDs returned from Cras DBus API.
196 Note that there may be multiple output/input nodes being selected
197 at the same time.
198
199 """
200 output_nodes = []
201 input_nodes = []
202 nodes = get_cras_nodes()
203 for node in nodes:
204 if node['Active']:
205 if node['IsInput']:
206 input_nodes.append(node['Id'])
207 else:
208 output_nodes.append(node['Id'])
209 return (output_nodes, input_nodes)
Owen Lin7ab45a22013-11-19 17:26:33 +0800210
Cheng-Yi Chiangc902f2e2015-03-09 10:45:44 +0800211
212def set_selected_output_node_volume(volume):
213 """Sets the selected output node volume.
214
215 @param volume: the volume to be set (0-100).
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800216
Cheng-Yi Chiangc902f2e2015-03-09 10:45:44 +0800217 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800218 selected_output_node_ids, _ = get_selected_nodes()
219 for node_id in selected_output_node_ids:
220 set_node_volume(node_id, volume)
Cheng-Yi Chiangc902f2e2015-03-09 10:45:44 +0800221
222
Owen Lin7ab45a22013-11-19 17:26:33 +0800223def get_active_stream_count():
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800224 """Gets the number of active streams.
225
226 @returns: The number of active streams.
227
228 """
229 return int(get_cras_control_interface().GetNumberOfActiveStreams())
Owen Lin56050862013-12-09 11:42:51 +0800230
231
232def set_system_mute(is_mute):
233 """Sets the system mute switch.
234
235 @param is_mute: Set True to mute the system playback.
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800236
Owen Lin56050862013-12-09 11:42:51 +0800237 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800238 get_cras_control_interface().SetOutputMute(is_mute)
Owen Lin56050862013-12-09 11:42:51 +0800239
240
241def set_capture_mute(is_mute):
242 """Sets the capture mute switch.
243
244 @param is_mute: Set True to mute the capture.
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800245
Owen Lin56050862013-12-09 11:42:51 +0800246 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800247 get_cras_control_interface().SetInputMute(is_mute)
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800248
249
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800250def node_type_is_plugged(node_type, nodes_info):
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800251 """Determine if there is any node of node_type plugged.
252
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800253 This method is used in has_loopback_dongle in cros_host, where
254 the call is executed on autotest server. Use get_cras_nodes instead if
255 the call can be executed on Cros device.
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800256
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800257 Since Cras only reports the plugged node in GetNodes, we can
258 parse the return value to see if there is any node with the given type.
259 For example, if INTERNAL_MIC is of intereset, the pattern we are
260 looking for is:
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800261
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800262 dict entry(
263 string "Type"
264 variant string "INTERNAL_MIC"
265 )
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800266
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800267 @param node_type: A str representing node type defined in CRAS_NODE_TYPES.
268 @param nodes_info: A str containing output of command get_nodes_cmd.
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800269
270 @returns: True if there is any node of node_type plugged. False otherwise.
271
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800272 """
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800273 match = re.search(r'string "Type"\s+variant\s+string "%s"' % node_type,
274 nodes_info)
275 return True if match else False
Cheng-Yi Chiangea5a71f2015-03-19 21:01:24 +0800276
277
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800278# Cras node types reported from Cras DBus control API.
Cheng-Yi Chiangea5a71f2015-03-19 21:01:24 +0800279CRAS_OUTPUT_NODE_TYPES = ['HEADPHONE', 'INTERNAL_SPEAKER', 'HDMI', 'USB',
Cheng-Yi Chiang4d022122015-09-20 22:53:24 -0700280 'BLUETOOTH', 'UNKNOWN']
281CRAS_INPUT_NODE_TYPES = ['MIC', 'INTERNAL_MIC', 'USB', 'BLUETOOTH',
Cheng-Yi Chiangd2fe0b42015-09-23 11:47:58 -0700282 'POST_DSP_LOOPBACK', 'POST_MIX_LOOPBACK', 'UNKNOWN',
283 'KEYBOARD_MIC', 'AOKR']
Cheng-Yi Chiangea5a71f2015-03-19 21:01:24 +0800284CRAS_NODE_TYPES = CRAS_OUTPUT_NODE_TYPES + CRAS_INPUT_NODE_TYPES
285
286
Cheng-Yi Chiang94edf0d2015-09-20 22:51:34 -0700287def get_filtered_node_types(callback):
288 """Returns the pair of filtered output node types and input node types.
289
290 @param callback: A callback function which takes a node as input parameter
291 and filter the node based on its return value.
Cheng-Yi Chiangea5a71f2015-03-19 21:01:24 +0800292
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800293 @returns: A tuple (output_node_types, input_node_types) where each
Cheng-Yi Chiang94edf0d2015-09-20 22:51:34 -0700294 field is a list of node types defined in CRAS_NODE_TYPES,
295 and their 'attribute_name' is True.
Cheng-Yi Chiangea5a71f2015-03-19 21:01:24 +0800296
297 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800298 output_node_types = []
299 input_node_types = []
300 nodes = get_cras_nodes()
301 for node in nodes:
Cheng-Yi Chiang94edf0d2015-09-20 22:51:34 -0700302 if callback(node):
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800303 node_type = str(node['Type'])
304 if node_type not in CRAS_NODE_TYPES:
305 raise RuntimeError(
306 'node type %s is not valid' % node_type)
307 if node['IsInput']:
308 input_node_types.append(node_type)
309 else:
310 output_node_types.append(node_type)
311 return (output_node_types, input_node_types)
Cheng-Yi Chianga22adaf2015-07-07 12:02:12 +0800312
313
Cheng-Yi Chiang94edf0d2015-09-20 22:51:34 -0700314def get_selected_node_types():
315 """Returns the pair of active output node types and input node types.
316
317 @returns: A tuple (output_node_types, input_node_types) where each
318 field is a list of selected node types defined in CRAS_NODE_TYPES.
319
320 """
321 def is_selected(node):
322 """Checks if a node is selected.
323
324 A node is selected if its Active attribute is True.
325
326 @returns: True is a node is selected, False otherwise.
327
328 """
329 return node['Active']
330
331 return get_filtered_node_types(is_selected)
332
333
334def get_plugged_node_types():
335 """Returns the pair of plugged output node types and input node types.
336
337 @returns: A tuple (output_node_types, input_node_types) where each
338 field is a list of plugged node types defined in CRAS_NODE_TYPES.
339
340 """
341 def is_plugged(node):
342 """Checks if a node is plugged and is not unknown node.
343
344 Cras DBus API only reports plugged node, so every node reported by Cras
345 DBus API is plugged. However, we filter out UNKNOWN node here because
346 the existence of unknown node depends on the number of redundant
347 playback/record audio device created on audio card. Also, the user of
348 Cras will ignore unknown nodes.
349
350 @returns: True if a node is plugged and is not an UNKNOWN node.
351
352 """
353 return node['Type'] != 'UNKNOWN'
354
355 return get_filtered_node_types(is_plugged)
356
357
Cheng-Yi Chianga22adaf2015-07-07 12:02:12 +0800358def set_selected_node_types(output_node_types, input_node_types):
359 """Sets selected node types.
360
361 @param output_node_types: A list of output node types. None to skip setting.
362 @param input_node_types: A list of input node types. None to skip setting.
363
364 """
Cheng-Yi Chiang271b5cb2015-09-22 22:54:41 -0700365 if len(output_node_types) == 1:
366 set_single_selected_output_node(output_node_types[0])
367 elif output_node_types:
Cheng-Yi Chianga22adaf2015-07-07 12:02:12 +0800368 set_selected_output_nodes(output_node_types)
Cheng-Yi Chiang271b5cb2015-09-22 22:54:41 -0700369 if len(input_node_types) == 1:
370 set_single_selected_input_node(input_node_types[0])
371 elif input_node_types:
Cheng-Yi Chianga22adaf2015-07-07 12:02:12 +0800372 set_selected_input_nodes(input_node_types)
373
374
Cheng-Yi Chiang271b5cb2015-09-22 22:54:41 -0700375def set_single_selected_output_node(node_type):
376 """Sets one selected output node.
377
378 Note that Chrome UI uses SetActiveOutputNode of Cras DBus API
379 to select one output node.
380
381 @param node_type: A node type.
382
383 """
384 nodes = get_cras_nodes()
385 for node in nodes:
386 if node['IsInput']:
387 continue
388 if node['Type'] == node_type:
389 set_active_output_node(node['Id'])
390
391
392def set_single_selected_input_node(node_type):
393 """Sets one selected input node.
394
395 Note that Chrome UI uses SetActiveInputNode of Cras DBus API
396 to select one input node.
397
398 @param node_type: A node type.
399
400 """
401 nodes = get_cras_nodes()
402 for node in nodes:
403 if not node['IsInput']:
404 continue
405 if node['Type'] == node_type:
406 set_active_input_node(node['Id'])
407
408
Cheng-Yi Chianga22adaf2015-07-07 12:02:12 +0800409def set_selected_output_nodes(types):
410 """Sets selected output node types.
411
412 Note that Chrome UI uses SetActiveOutputNode of Cras DBus API
413 to select one output node. Here we use add/remove active output node
414 to support multiple nodes.
415
416 @param types: A list of output node types.
417
418 """
419 nodes = get_cras_nodes()
420 for node in nodes:
421 if node['IsInput']:
422 continue
423 if node['Type'] in types:
424 add_active_output_node(node['Id'])
425 elif node['Active']:
426 remove_active_output_node(node['Id'])
427
428
429def set_selected_input_nodes(types):
430 """Sets selected input node types.
431
432 Note that Chrome UI uses SetActiveInputNode of Cras DBus API
433 to select one input node. Here we use add/remove active input node
434 to support multiple nodes.
435
436 @param types: A list of input node types.
437
438 """
439 nodes = get_cras_nodes()
440 for node in nodes:
441 if not node['IsInput']:
442 continue
443 if node['Type'] in types:
444 add_active_input_node(node['Id'])
445 elif node['Active']:
446 remove_active_input_node(node['Id'])
447
448
Cheng-Yi Chiang271b5cb2015-09-22 22:54:41 -0700449def set_active_input_node(node_id):
450 """Sets one active input node.
451
452 @param node_id: node id.
453
454 """
455 get_cras_control_interface().SetActiveInputNode(node_id)
456
457
458def set_active_output_node(node_id):
459 """Sets one active output node.
460
461 @param node_id: node id.
462
463 """
464 get_cras_control_interface().SetActiveOutputNode(node_id)
465
466
Cheng-Yi Chianga22adaf2015-07-07 12:02:12 +0800467def add_active_output_node(node_id):
468 """Adds an active output node.
469
470 @param node_id: node id.
471
472 """
473 get_cras_control_interface().AddActiveOutputNode(node_id)
474
475
476def add_active_input_node(node_id):
477 """Adds an active input node.
478
479 @param node_id: node id.
480
481 """
482 get_cras_control_interface().AddActiveInputNode(node_id)
483
484
485def remove_active_output_node(node_id):
486 """Removes an active output node.
487
488 @param node_id: node id.
489
490 """
491 get_cras_control_interface().RemoveActiveOutputNode(node_id)
492
493
494def remove_active_input_node(node_id):
495 """Removes an active input node.
496
497 @param node_id: node id.
498
499 """
500 get_cras_control_interface().RemoveActiveInputNode(node_id)
Cheng-Yi Chiang08c25492015-11-06 15:15:49 +0800501
502
Cheng-Yi Chiang8e18acc2015-11-19 08:33:46 +0800503def get_node_id_from_node_type(node_type, is_input):
Cheng-Yi Chiang08c25492015-11-06 15:15:49 +0800504 """Gets node id from node type.
505
506 @param types: A node type defined in CRAS_NODE_TYPES.
Cheng-Yi Chiang8e18acc2015-11-19 08:33:46 +0800507 @param is_input: True if the node is input. False otherwise.
508
509 @returns: A string for node id.
510
511 @raises: CrasUtilsError: if unique node id can not be found.
Cheng-Yi Chiang08c25492015-11-06 15:15:49 +0800512
513 """
514 nodes = get_cras_nodes()
515 find_ids = []
516 for node in nodes:
Cheng-Yi Chiang8e18acc2015-11-19 08:33:46 +0800517 if node['Type'] == node_type and node['IsInput'] == is_input:
Cheng-Yi Chiang08c25492015-11-06 15:15:49 +0800518 find_ids.append(node['Id'])
519 if len(find_ids) != 1:
520 raise CrasUtilsError(
521 'Can not find unique node id from node type %s' % node_type)
522 return find_ids[0]