• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2013 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
5import re
6
7from autotest_lib.client.bin import test, utils
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.cros.audio import alsa_utils
10
11
12APLAY_FILE = '/dev/zero' # raw data
13
14# Expected results of 'aplay -v' commands.
15APLAY_EXPECTED = set([
16      ('stream', 'PLAYBACK')])
17
18
19def _play_audio(duration=1):
20    """Play a tone and try to ensure it played properly.
21
22    Sample output from aplay -v:
23
24    Playing raw data '/dev/zero' : Signed 16 bit Little Endian, Rate 44100 Hz,
25    Stereo
26    Hardware PCM card 0 'HDA Intel PCH' device 0 subdevice 0
27    Its setup is:
28      stream       : PLAYBACK
29      access       : RW_INTERLEAVED  format       : S16_LE
30      subformat    : STD
31      channels     : 2
32      rate         : 44100
33      exact rate   : 44100 (44100/1)
34      msbits       : 16
35      buffer_size  : 16384
36      period_size  : 4096
37      period_time  : 92879
38      tstamp_mode  : NONE
39      period_step  : 1
40      avail_min    : 4096
41      period_event : 0
42      start_threshold  : 16384
43      stop_threshold   : 16384
44      silence_threshold: 0
45      silence_size : 0
46      boundary     : 4611686018427387904
47      appl_ptr     : 0
48      hw_ptr       : 0
49
50    @param duration: Duration supplied to aplay.
51    @return String output from the command (may be empty).
52    @raises CmdError when cmd returns <> 0.
53    """
54    device = alsa_utils.get_sysdefault_playback_device()
55    cmd = ['aplay',
56           '-v', # show verbose details
57           '-D %s' % device,  # select default device
58           '-d %d' % duration,
59           '-f cd', # format
60           APLAY_FILE,
61           '2>&1'] # verbose details
62    return utils.system_output(' '.join(cmd)).strip()
63
64
65def _check_play(duration, expected):
66    """Runs aplay command and checks the output against an expected result.
67
68    The expected results are compared as sets of tuples.
69
70    @param duration: Duration supplied to aplay.
71    @param expected: The set of expected tuples.
72    @raises error.TestError for invalid output or invalidly matching expected.
73    """
74    error_msg = 'invalid response from aplay'
75    results = _play_audio(duration)
76    if not results.startswith("Playing raw data '%s' :" % APLAY_FILE):
77        raise error.TestError('%s: %s' % (error_msg, results))
78    result_set = utils.set_from_keyval_output(results, '[\s]*:[\s]*')
79    if set(expected) <= result_set:
80        return
81    raise error.TestError('%s: expected=%s.' %
82                          (error_msg, sorted(set(expected) - result_set)))
83
84
85class audio_Aplay(test.test):
86    """Checks that simple aplay functions correctly."""
87    version = 1
88
89
90    def run_once(self, duration=1):
91        """Run aplay and verify its output is as expected.
92
93        @param duration: the duration to run aplay in seconds.
94        """
95        _check_play(duration, APLAY_EXPECTED)
96