blob: 26301fbb9bd07b3d1118a0476796dad784d8f21a [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
Chen-Hao Chang@google.comef6b4282016-08-23 12:05:57 +080019def playback(blocking=True, *args, **kargs):
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080020 """A helper function to execute the playback_cmd.
21
Chen-Hao Chang@google.comef6b4282016-08-23 12:05:57 +080022 @param blocking: Blocks this call until playback finishes.
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080023 @param args: args passed to playback_cmd.
24 @param kargs: kargs passed to playback_cmd.
25
Chen-Hao Chang@google.comef6b4282016-08-23 12:05:57 +080026 @returns: The process running the playback command. Note that if the
27 blocking parameter is true, this will return a finished process.
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080028 """
Chen-Hao Chang@google.comef6b4282016-08-23 12:05:57 +080029 process = cmd_utils.popen(playback_cmd(*args, **kargs))
30 if blocking:
31 cmd_utils.wait_and_check_returncode(process)
32 return process
Owen Linca365f82013-11-08 16:52:28 +080033
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +080034
Owen Linca365f82013-11-08 16:52:28 +080035def capture(*args, **kargs):
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080036 """A helper function to execute the capture_cmd.
37
38 @param args: args passed to capture_cmd.
39 @param kargs: kargs passed to capture_cmd.
40
41 """
Owen Lin9d19b272013-11-28 12:13:24 +080042 cmd_utils.execute(capture_cmd(*args, **kargs))
Owen Linca365f82013-11-08 16:52:28 +080043
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +080044
Owen Lin2f7e7f42013-12-25 17:25:43 +080045def playback_cmd(playback_file, block_size=None, duration=None,
Owen Lin2013e462013-12-05 17:54:42 +080046 channels=2, rate=48000):
Owen Linca365f82013-11-08 16:52:28 +080047 """Gets a command to playback a file with given settings.
48
49 @param playback_file: the name of the file to play. '-' indicates to
50 playback raw audio from the stdin.
Owen Lin2f7e7f42013-12-25 17:25:43 +080051 @param block_size: the number of frames per callback(dictates latency).
Owen Linca365f82013-11-08 16:52:28 +080052 @param duration: seconds to playback
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080053 @param channels: number of channels.
Owen Linca365f82013-11-08 16:52:28 +080054 @param rate: the sampling rate
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +080055
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080056 @returns: The command args put in a list of strings.
57
Owen Linca365f82013-11-08 16:52:28 +080058 """
59 args = [_CRAS_TEST_CLIENT]
60 args += ['--playback_file', playback_file]
Owen Lin2f7e7f42013-12-25 17:25:43 +080061 if block_size is not None:
62 args += ['--block_size', str(block_size)]
Owen Linca365f82013-11-08 16:52:28 +080063 if duration is not None:
64 args += ['--duration', str(duration)]
Owen Lin2013e462013-12-05 17:54:42 +080065 args += ['--num_channels', str(channels)]
Owen Linca365f82013-11-08 16:52:28 +080066 args += ['--rate', str(rate)]
67 return args
68
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +080069
Owen Lina8129c62013-11-26 16:51:46 +080070def capture_cmd(
Owen Lin2f7e7f42013-12-25 17:25:43 +080071 capture_file, block_size=None, duration=10, channels=1, rate=48000):
Owen Linca365f82013-11-08 16:52:28 +080072 """Gets a command to capture the audio into the file with given settings.
73
74 @param capture_file: the name of file the audio to be stored in.
Owen Lin2f7e7f42013-12-25 17:25:43 +080075 @param block_size: the number of frames per callback(dictates latency).
Cheng-Yi Chiangeaf53292015-01-12 20:53:56 +080076 @param duration: seconds to record. If it is None, duration is not set,
77 and command will keep capturing audio until it is
78 terminated.
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080079 @param channels: number of channels.
Owen Linca365f82013-11-08 16:52:28 +080080 @param rate: the sampling rate.
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +080081
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080082 @returns: The command args put in a list of strings.
83
Owen Linca365f82013-11-08 16:52:28 +080084 """
85 args = [_CRAS_TEST_CLIENT]
86 args += ['--capture_file', capture_file]
Owen Lin2f7e7f42013-12-25 17:25:43 +080087 if block_size is not None:
88 args += ['--block_size', str(block_size)]
Cheng-Yi Chiangeaf53292015-01-12 20:53:56 +080089 if duration is not None:
90 args += ['--duration', str(duration)]
Owen Lina8129c62013-11-26 16:51:46 +080091 args += ['--num_channels', str(channels)]
Owen Linca365f82013-11-08 16:52:28 +080092 args += ['--rate', str(rate)]
93 return args
94
Owen Lindae7a0d2013-12-05 13:34:06 +080095
96def loopback(*args, **kargs):
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +080097 """A helper function to execute loopback_cmd.
98
99 @param args: args passed to loopback_cmd.
100 @param kargs: kargs passed to loopback_cmd.
101
102 """
103
Owen Lindae7a0d2013-12-05 13:34:06 +0800104 cmd_utils.execute(loopback_cmd(*args, **kargs))
105
106
Owen Lin2013e462013-12-05 17:54:42 +0800107def loopback_cmd(output_file, duration=10, channels=2, rate=48000):
Owen Lindae7a0d2013-12-05 13:34:06 +0800108 """Gets a command to record the loopback.
109
110 @param output_file: The name of the file the loopback to be stored in.
111 @param channels: The number of channels of the recorded audio.
112 @param duration: seconds to record.
113 @param rate: the sampling rate.
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800114
Cheng-Yi Chiangaaa0a5e2015-05-27 12:09:17 +0800115 @returns: The command args put in a list of strings.
116
Owen Lindae7a0d2013-12-05 13:34:06 +0800117 """
118 args = [_CRAS_TEST_CLIENT]
119 args += ['--loopback_file', output_file]
120 args += ['--duration_seconds', str(duration)]
121 args += ['--num_channels', str(channels)]
122 args += ['--rate', str(rate)]
123 return args
124
125
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800126def get_cras_nodes_cmd():
127 """Gets a command to query the nodes from Cras.
128
129 @returns: The command to query nodes information from Cras using dbus-send.
130
131 """
132 return ('dbus-send --system --type=method_call --print-reply '
133 '--dest=org.chromium.cras /org/chromium/cras '
134 'org.chromium.cras.Control.GetNodes')
135
136
Owen Linca365f82013-11-08 16:52:28 +0800137def set_system_volume(volume):
138 """Set the system volume.
139
140 @param volume: the system output vlume to be set(0 - 100).
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800141
Owen Linca365f82013-11-08 16:52:28 +0800142 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800143 get_cras_control_interface().SetOutputVolume(volume)
Owen Linca365f82013-11-08 16:52:28 +0800144
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800145
Owen Linca365f82013-11-08 16:52:28 +0800146def set_node_volume(node_id, volume):
147 """Set the volume of the given output node.
148
149 @param node_id: the id of the output node to be set the volume.
150 @param volume: the volume to be set(0-100).
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800151
Owen Linca365f82013-11-08 16:52:28 +0800152 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800153 get_cras_control_interface().SetOutputNodeVolume(node_id, volume)
Owen Linca365f82013-11-08 16:52:28 +0800154
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800155
Owen Linca365f82013-11-08 16:52:28 +0800156def set_capture_gain(gain):
157 """Set the system capture gain.
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800158
Owen Linca365f82013-11-08 16:52:28 +0800159 @param gain the capture gain in db*100 (100 = 1dB)
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800160
Owen Linca365f82013-11-08 16:52:28 +0800161 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800162 get_cras_control_interface().SetInputGain(gain)
Owen Linca365f82013-11-08 16:52:28 +0800163
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800164
Cheng-Yi Chiang3dd376d2015-10-20 16:28:21 +0800165def get_cras_control_interface(private=False):
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800166 """Gets Cras DBus control interface.
167
Cheng-Yi Chiang3dd376d2015-10-20 16:28:21 +0800168 @param private: Set to True to use a new instance for dbus.SystemBus
169 instead of the shared instance.
170
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800171 @returns: A dBus.Interface object with Cras Control interface.
172
173 @raises: ImportError if this is not called on Cros device.
174
175 """
176 try:
177 import dbus
178 except ImportError, e:
179 logging.exception(
180 'Can not import dbus: %s. This method should only be '
181 'called on Cros device.', e)
182 raise
Cheng-Yi Chiang3dd376d2015-10-20 16:28:21 +0800183 bus = dbus.SystemBus(private=private)
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800184 cras_object = bus.get_object('org.chromium.cras', '/org/chromium/cras')
185 return dbus.Interface(cras_object, 'org.chromium.cras.Control')
186
187
188def get_cras_nodes():
189 """Gets nodes information from Cras.
190
191 @returns: A dict containing information of each node.
192
193 """
194 return get_cras_control_interface().GetNodes()
Owen Linca365f82013-11-08 16:52:28 +0800195
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800196
Owen Linca365f82013-11-08 16:52:28 +0800197def get_selected_nodes():
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800198 """Gets selected output nodes and input nodes.
Owen Linca365f82013-11-08 16:52:28 +0800199
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800200 @returns: A tuple (output_nodes, input_nodes) where each
201 field is a list of selected node IDs returned from Cras DBus API.
202 Note that there may be multiple output/input nodes being selected
203 at the same time.
204
205 """
206 output_nodes = []
207 input_nodes = []
208 nodes = get_cras_nodes()
209 for node in nodes:
210 if node['Active']:
211 if node['IsInput']:
212 input_nodes.append(node['Id'])
213 else:
214 output_nodes.append(node['Id'])
215 return (output_nodes, input_nodes)
Owen Lin7ab45a22013-11-19 17:26:33 +0800216
Cheng-Yi Chiangc902f2e2015-03-09 10:45:44 +0800217
218def set_selected_output_node_volume(volume):
219 """Sets the selected output node volume.
220
221 @param volume: the volume to be set (0-100).
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800222
Cheng-Yi Chiangc902f2e2015-03-09 10:45:44 +0800223 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800224 selected_output_node_ids, _ = get_selected_nodes()
225 for node_id in selected_output_node_ids:
226 set_node_volume(node_id, volume)
Cheng-Yi Chiangc902f2e2015-03-09 10:45:44 +0800227
228
Owen Lin7ab45a22013-11-19 17:26:33 +0800229def get_active_stream_count():
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800230 """Gets the number of active streams.
231
232 @returns: The number of active streams.
233
234 """
235 return int(get_cras_control_interface().GetNumberOfActiveStreams())
Owen Lin56050862013-12-09 11:42:51 +0800236
237
238def set_system_mute(is_mute):
239 """Sets the system mute switch.
240
241 @param is_mute: Set True to mute the system playback.
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800242
Owen Lin56050862013-12-09 11:42:51 +0800243 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800244 get_cras_control_interface().SetOutputMute(is_mute)
Owen Lin56050862013-12-09 11:42:51 +0800245
246
247def set_capture_mute(is_mute):
248 """Sets the capture mute switch.
249
250 @param is_mute: Set True to mute the capture.
Cheng-Yi Chiangb0ec9042015-03-10 15:45:18 +0800251
Owen Lin56050862013-12-09 11:42:51 +0800252 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800253 get_cras_control_interface().SetInputMute(is_mute)
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800254
255
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800256def node_type_is_plugged(node_type, nodes_info):
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800257 """Determine if there is any node of node_type plugged.
258
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800259 This method is used in has_loopback_dongle in cros_host, where
260 the call is executed on autotest server. Use get_cras_nodes instead if
261 the call can be executed on Cros device.
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800262
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800263 Since Cras only reports the plugged node in GetNodes, we can
264 parse the return value to see if there is any node with the given type.
265 For example, if INTERNAL_MIC is of intereset, the pattern we are
266 looking for is:
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800267
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800268 dict entry(
269 string "Type"
270 variant string "INTERNAL_MIC"
271 )
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800272
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800273 @param node_type: A str representing node type defined in CRAS_NODE_TYPES.
274 @param nodes_info: A str containing output of command get_nodes_cmd.
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800275
276 @returns: True if there is any node of node_type plugged. False otherwise.
277
Cheng-Yi Chiangf4104ff2014-12-23 19:39:01 +0800278 """
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800279 match = re.search(r'string "Type"\s+variant\s+string "%s"' % node_type,
280 nodes_info)
281 return True if match else False
Cheng-Yi Chiangea5a71f2015-03-19 21:01:24 +0800282
283
Cheng-Yi Chiang8de78112015-05-27 14:47:08 +0800284# Cras node types reported from Cras DBus control API.
Cheng-Yi Chiangea5a71f2015-03-19 21:01:24 +0800285CRAS_OUTPUT_NODE_TYPES = ['HEADPHONE', 'INTERNAL_SPEAKER', 'HDMI', 'USB',
Cheng-Yi Chiang4d022122015-09-20 22:53:24 -0700286 'BLUETOOTH', 'UNKNOWN']
287CRAS_INPUT_NODE_TYPES = ['MIC', 'INTERNAL_MIC', 'USB', 'BLUETOOTH',
Cheng-Yi Chiangd2fe0b42015-09-23 11:47:58 -0700288 'POST_DSP_LOOPBACK', 'POST_MIX_LOOPBACK', 'UNKNOWN',
Kalin Stoyanov203fdb92016-05-02 17:48:20 -0700289 'KEYBOARD_MIC', 'HOTWORD']
Cheng-Yi Chiangea5a71f2015-03-19 21:01:24 +0800290CRAS_NODE_TYPES = CRAS_OUTPUT_NODE_TYPES + CRAS_INPUT_NODE_TYPES
291
292
Cheng-Yi Chiang94edf0d2015-09-20 22:51:34 -0700293def get_filtered_node_types(callback):
294 """Returns the pair of filtered output node types and input node types.
295
296 @param callback: A callback function which takes a node as input parameter
297 and filter the node based on its return value.
Cheng-Yi Chiangea5a71f2015-03-19 21:01:24 +0800298
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800299 @returns: A tuple (output_node_types, input_node_types) where each
Cheng-Yi Chiang94edf0d2015-09-20 22:51:34 -0700300 field is a list of node types defined in CRAS_NODE_TYPES,
301 and their 'attribute_name' is True.
Cheng-Yi Chiangea5a71f2015-03-19 21:01:24 +0800302
303 """
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800304 output_node_types = []
305 input_node_types = []
306 nodes = get_cras_nodes()
307 for node in nodes:
Cheng-Yi Chiang94edf0d2015-09-20 22:51:34 -0700308 if callback(node):
Cheng-Yi Chiang79b9ada2015-05-27 14:46:56 +0800309 node_type = str(node['Type'])
310 if node_type not in CRAS_NODE_TYPES:
311 raise RuntimeError(
312 'node type %s is not valid' % node_type)
313 if node['IsInput']:
314 input_node_types.append(node_type)
315 else:
316 output_node_types.append(node_type)
317 return (output_node_types, input_node_types)
Cheng-Yi Chianga22adaf2015-07-07 12:02:12 +0800318
319
Cheng-Yi Chiang94edf0d2015-09-20 22:51:34 -0700320def get_selected_node_types():
321 """Returns the pair of active output node types and input node types.
322
323 @returns: A tuple (output_node_types, input_node_types) where each
324 field is a list of selected node types defined in CRAS_NODE_TYPES.
325
326 """
327 def is_selected(node):
328 """Checks if a node is selected.
329
330 A node is selected if its Active attribute is True.
331
332 @returns: True is a node is selected, False otherwise.
333
334 """
335 return node['Active']
336
337 return get_filtered_node_types(is_selected)
338
339
340def get_plugged_node_types():
341 """Returns the pair of plugged output node types and input node types.
342
343 @returns: A tuple (output_node_types, input_node_types) where each
344 field is a list of plugged node types defined in CRAS_NODE_TYPES.
345
346 """
347 def is_plugged(node):
348 """Checks if a node is plugged and is not unknown node.
349
350 Cras DBus API only reports plugged node, so every node reported by Cras
351 DBus API is plugged. However, we filter out UNKNOWN node here because
352 the existence of unknown node depends on the number of redundant
353 playback/record audio device created on audio card. Also, the user of
354 Cras will ignore unknown nodes.
355
356 @returns: True if a node is plugged and is not an UNKNOWN node.
357
358 """
359 return node['Type'] != 'UNKNOWN'
360
361 return get_filtered_node_types(is_plugged)
362
363
Cheng-Yi Chianga22adaf2015-07-07 12:02:12 +0800364def set_selected_node_types(output_node_types, input_node_types):
365 """Sets selected node types.
366
367 @param output_node_types: A list of output node types. None to skip setting.
368 @param input_node_types: A list of input node types. None to skip setting.
369
370 """
Cheng-Yi Chiang271b5cb2015-09-22 22:54:41 -0700371 if len(output_node_types) == 1:
372 set_single_selected_output_node(output_node_types[0])
373 elif output_node_types:
Cheng-Yi Chianga22adaf2015-07-07 12:02:12 +0800374 set_selected_output_nodes(output_node_types)
Cheng-Yi Chiang271b5cb2015-09-22 22:54:41 -0700375 if len(input_node_types) == 1:
376 set_single_selected_input_node(input_node_types[0])
377 elif input_node_types:
Cheng-Yi Chianga22adaf2015-07-07 12:02:12 +0800378 set_selected_input_nodes(input_node_types)
379
380
Cheng-Yi Chiang271b5cb2015-09-22 22:54:41 -0700381def set_single_selected_output_node(node_type):
382 """Sets one selected output node.
383
384 Note that Chrome UI uses SetActiveOutputNode of Cras DBus API
385 to select one output node.
386
387 @param node_type: A node type.
388
389 """
390 nodes = get_cras_nodes()
391 for node in nodes:
392 if node['IsInput']:
393 continue
394 if node['Type'] == node_type:
395 set_active_output_node(node['Id'])
396
397
398def set_single_selected_input_node(node_type):
399 """Sets one selected input node.
400
401 Note that Chrome UI uses SetActiveInputNode of Cras DBus API
402 to select one input node.
403
404 @param node_type: A node type.
405
406 """
407 nodes = get_cras_nodes()
408 for node in nodes:
409 if not node['IsInput']:
410 continue
411 if node['Type'] == node_type:
412 set_active_input_node(node['Id'])
413
414
Cheng-Yi Chianga22adaf2015-07-07 12:02:12 +0800415def set_selected_output_nodes(types):
416 """Sets selected output node types.
417
418 Note that Chrome UI uses SetActiveOutputNode of Cras DBus API
419 to select one output node. Here we use add/remove active output node
420 to support multiple nodes.
421
422 @param types: A list of output node types.
423
424 """
425 nodes = get_cras_nodes()
426 for node in nodes:
427 if node['IsInput']:
428 continue
429 if node['Type'] in types:
430 add_active_output_node(node['Id'])
431 elif node['Active']:
432 remove_active_output_node(node['Id'])
433
434
435def set_selected_input_nodes(types):
436 """Sets selected input node types.
437
438 Note that Chrome UI uses SetActiveInputNode of Cras DBus API
439 to select one input node. Here we use add/remove active input node
440 to support multiple nodes.
441
442 @param types: A list of input node types.
443
444 """
445 nodes = get_cras_nodes()
446 for node in nodes:
447 if not node['IsInput']:
448 continue
449 if node['Type'] in types:
450 add_active_input_node(node['Id'])
451 elif node['Active']:
452 remove_active_input_node(node['Id'])
453
454
Cheng-Yi Chiang271b5cb2015-09-22 22:54:41 -0700455def set_active_input_node(node_id):
456 """Sets one active input node.
457
458 @param node_id: node id.
459
460 """
461 get_cras_control_interface().SetActiveInputNode(node_id)
462
463
464def set_active_output_node(node_id):
465 """Sets one active output node.
466
467 @param node_id: node id.
468
469 """
470 get_cras_control_interface().SetActiveOutputNode(node_id)
471
472
Cheng-Yi Chianga22adaf2015-07-07 12:02:12 +0800473def add_active_output_node(node_id):
474 """Adds an active output node.
475
476 @param node_id: node id.
477
478 """
479 get_cras_control_interface().AddActiveOutputNode(node_id)
480
481
482def add_active_input_node(node_id):
483 """Adds an active input node.
484
485 @param node_id: node id.
486
487 """
488 get_cras_control_interface().AddActiveInputNode(node_id)
489
490
491def remove_active_output_node(node_id):
492 """Removes an active output node.
493
494 @param node_id: node id.
495
496 """
497 get_cras_control_interface().RemoveActiveOutputNode(node_id)
498
499
500def remove_active_input_node(node_id):
501 """Removes an active input node.
502
503 @param node_id: node id.
504
505 """
506 get_cras_control_interface().RemoveActiveInputNode(node_id)
Cheng-Yi Chiang08c25492015-11-06 15:15:49 +0800507
508
Cheng-Yi Chiang8e18acc2015-11-19 08:33:46 +0800509def get_node_id_from_node_type(node_type, is_input):
Cheng-Yi Chiang08c25492015-11-06 15:15:49 +0800510 """Gets node id from node type.
511
512 @param types: A node type defined in CRAS_NODE_TYPES.
Cheng-Yi Chiang8e18acc2015-11-19 08:33:46 +0800513 @param is_input: True if the node is input. False otherwise.
514
515 @returns: A string for node id.
516
517 @raises: CrasUtilsError: if unique node id can not be found.
Cheng-Yi Chiang08c25492015-11-06 15:15:49 +0800518
519 """
520 nodes = get_cras_nodes()
521 find_ids = []
522 for node in nodes:
Cheng-Yi Chiang8e18acc2015-11-19 08:33:46 +0800523 if node['Type'] == node_type and node['IsInput'] == is_input:
Cheng-Yi Chiang08c25492015-11-06 15:15:49 +0800524 find_ids.append(node['Id'])
525 if len(find_ids) != 1:
526 raise CrasUtilsError(
527 'Can not find unique node id from node type %s' % node_type)
528 return find_ids[0]