blob: 9281ca7a1881440f92b8b180aa94232c4a75f6b0 [file] [log] [blame]
Owen Lin21d49eb2013-12-03 10:47:58 +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
5import shlex
6import subprocess
7
8from autotest_lib.client.cros.audio import cmd_utils
9
10ARECORD_PATH='/usr/bin/arecord'
11APLAY_PATH='/usr/bin/aplay'
Owen Lin56050862013-12-09 11:42:51 +080012AMIXER_PATH='/usr/bin/amixer'
Owen Lin21d49eb2013-12-03 10:47:58 +080013
14def _get_format_args(channels, bits, rate):
15 args = ['-c', str(channels)]
16 args += ['-f', 'S%d_LE' % bits]
17 args += ['-r', str(rate)]
18 return args
19
20
21def _get_default_device():
22 return 'plughw:%d' % get_default_soundcard_id()
23
24
25def playback(*args, **kargs):
26 '''A helper funciton to execute playback_cmd.'''
27 cmd_utils.execute(playback_cmd(*args, **kargs))
28
29
30def playback_cmd(
Owen Lin2013e462013-12-05 17:54:42 +080031 input, duration=None, channels=2, bits=16, rate=48000, device=None):
Owen Lin21d49eb2013-12-03 10:47:58 +080032 '''Plays the given input audio by the ALSA utility: 'aplay'.
33
34 @param input: The input audio to be played.
35 @param duration: The length of the playback (in seconds).
36 @param channels: The number of channels of the input audio.
37 @param bits: The number of bits of each audio sample.
38 @param rate: The sampling rate.
39 @param device: The device to play the audio on.
40 '''
41 args = [APLAY_PATH]
42 if duration is not None:
43 args += ['-d', str(duration)]
44 args += _get_format_args(channels, bits, rate)
45 if device is None:
46 device = _get_default_device()
47 args += ['-D', device]
48 args += [input]
49 return args
50
51
52def record(*args, **kargs):
53 '''A helper function to execute record_cmd.'''
54 cmd_utils.execute(record_cmd(*args, **kargs))
55
56
57def record_cmd(
Owen Lin2013e462013-12-05 17:54:42 +080058 output, duration=None, channels=1, bits=16, rate=48000, device=None):
Owen Lin21d49eb2013-12-03 10:47:58 +080059 '''Records the audio to the specified output by ALSA utility: 'arecord'.
60
61 @param output: The filename where the recorded audio will be stored to.
62 @param duration: The length of the recording (in seconds).
63 @param channels: The number of channels of the recorded audio.
64 @param bits: The number of bits of each audio sample.
65 @param rate: The sampling rate.
66 @param device: The device used to recorded the audio from.
67 '''
68 args = [ARECORD_PATH]
69 if duration is not None:
70 args += ['-d', str(duration)]
71 args += _get_format_args(channels, bits, rate)
72 if device is None:
73 device = _get_default_device()
74 args += ['-D', device]
75 args += [output]
76 return args
77
78
79_default_soundcard_id = -1
80
81def get_default_soundcard_id():
82 '''Gets the ID of the default soundcard.
83
84 @raise RuntimeError: if it fails to find the default soundcard id.
85 '''
86 global _default_soundcard_id
87 if _default_soundcard_id == -1:
88 _default_soundcard_id = _find_default_soundcard_id()
89
90 if _default_soundcard_id is None:
91 raise RuntimeError('no soundcard found')
92 return _default_soundcard_id
93
94
95def _find_default_soundcard_id():
96 '''Finds the id of the default hardware soundcard.'''
97
98 # If there is only one card, choose it; otherwise,
99 # choose the first card with controls named 'Speaker'
100 cmd = 'amixer -c %d scontrols'
101 id = 0
102 while True:
103 p = cmd_utils.popen(shlex.split(cmd % id), stdout=subprocess.PIPE)
104 output, _ = p.communicate()
105 if p.wait() != 0: # end of the card list
106 break;
107 if 'speaker' in output.lower():
108 return id
109 id = id + 1
110
111 # If there is only one soundcard, return it, else return not found (None)
112 return 0 if id == 1 else None
Owen Lin56050862013-12-09 11:42:51 +0800113
114def dump_control_contents(device=None):
115 if device is None:
116 device = 'hw:%d' % get_default_soundcard_id()
117 args = [AMIXER_PATH, '-D', device, 'contents']
118 return cmd_utils.execute(args, stdout=subprocess.PIPE)