• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 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
5"""This module provides the audio widgets related to ARC used in audio tests."""
6
7import copy
8import tempfile
9
10from autotest_lib.client.cros.audio import audio_test_data
11from autotest_lib.client.cros.chameleon import audio_widget
12
13class CrosInputWidgetARCHandler(audio_widget.CrosInputWidgetHandler):
14    """
15
16    This class abstracts a Cros device audio input widget ARC handler.
17
18    """
19    # AMR-NB uses variable bit rates so we set sample_format to None.
20    # Other format info are actually useless for sox because sox can read them
21    # from file header.
22    _SOURCE_FORMAT = dict(file_type='amr-nb',
23                          sample_format=None,
24                          channel=1,
25                          rate=8000)
26
27    def start_recording(self, **kargs):
28        """Starts recording audio through ARC.
29
30        @param kargs: Other arguments that ARC doesn't support.
31
32        """
33        self._audio_facade.start_arc_recording()
34
35
36    def stop_recording(self, **kargs):
37        """Stops recording audio through ARC.
38
39        @param kargs: Other arguments that ARC doesn't support.
40
41        @returns:
42            A tuple (remote_path, format).
43                remote_path: The path to the recorded file on Cros device.
44                format: A dict containing:
45                    file_type: 'raw'.
46                    sample_format: 'S16_LE' for 16-bit signed integer in
47                                   little-endian.
48                    channel: channel number.
49                    rate: sampling rate.
50
51        """
52        return (self._audio_facade.stop_arc_recording(),
53                self._DEFAULT_DATA_FORMAT)
54
55
56    def get_recorded_binary(self, remote_path, record_format):
57        """Gets remote recorded file binary from Cros device..
58
59        Gets and reads recorded file from Cros device.
60        The argument 'record_format' is what API user want on output.
61        The real file format of file at 'remote_path' can be another source
62        format. This method handles the format conversion from source format
63        into record_format, and returns the converted binary.
64
65        Handle the format conversion from source format into record_format.
66
67        @param remote_path: The path to the recorded file on Cros device.
68        @param record_format: The data format of returned binary.
69                     A dict containing
70                     file_type: 'raw' or 'wav'.
71                     sample_format: 'S32_LE' for 32-bit signed integer in
72                                    little-endian. Refer to aplay manpage for
73                                    other formats.
74                     channel: channel number.
75                     rate: sampling rate.
76
77        @returns: The recorded binary.
78
79        @raises: CrosInputWidgetHandlerError if record_format is not correct.
80
81        """
82        if record_format != self._DEFAULT_DATA_FORMAT:
83            raise audio_widget.CrosInputWidgetHandlerError(
84                    'Record format %r is not valid' % record_format)
85
86        ext = '.' + self._SOURCE_FORMAT['file_type']
87        with tempfile.NamedTemporaryFile(prefix='recorded_', suffix=ext) as f:
88            self._audio_facade.get_recorded_file(remote_path, f.name)
89
90            # Handles conversion from source format into record_format.
91            test_data = audio_test_data.AudioTestData(
92                    self._SOURCE_FORMAT, f.name)
93            converted_test_data = test_data.convert(record_format, 1.0)
94            try:
95                return converted_test_data.get_binary()
96            finally:
97                converted_test_data.delete()
98
99
100class CrosOutputWidgetARCHandlerError(Exception):
101    """Error in CrosOutputWidgetARCHandler."""
102    pass
103
104
105class CrosOutputWidgetARCHandler(audio_widget.CrosOutputWidgetHandler):
106    """This class abstracts a Cros device audio output widget ARC handler."""
107    _SUPPORTED_FILE_TYPES = ['wav', 'mp3']
108    _DEFAULT_FILE_TYPE = 'wav'
109
110    def set_playback_data(self, test_data):
111        """Sets data to play.
112
113        @param test_data: An AudioTestData object.
114
115        @returns: Path to the file in container on Cros host.
116
117        """
118        # Handle the format conversion because ARC does not recognize raw file.
119        if test_data.data_format['file_type'] not in self._SUPPORTED_FILE_TYPES:
120            new_data_format = copy.deepcopy(test_data.data_format)
121            new_data_format['file_type'] = self._DEFAULT_FILE_TYPE
122            test_data = test_data.convert(new_data_format, 1.0)
123        return self._audio_facade.set_arc_playback_file(test_data.path)
124
125
126    def start_playback(self, path, blocking=False, **kargs):
127        """Starts playing audio.
128
129        @param path: Path to the file to play in container on Cros host.
130        @param blocking: Blocks this call until playback finishes.
131        @param kargs: Other arguments that ARC doesn't support.
132
133        @raises: NotImplementedError if blocking is True.
134
135        """
136        if blocking:
137            raise NotImplementedError(
138                    'Blocking playback on ARC is not supported.')
139
140        self._audio_facade.start_arc_playback(path)
141
142
143    def stop_playback(self):
144        """Stops playing audio."""
145        self._audio_facade.stop_arc_playback()
146