def _prepare_impl(self, use_file, sample_width, sample_rate, num_channels,
                      frequency):
        """Prepare for audio recording (interface override).

        @param use_file: If a file was used to produce audio. This is necessary
                         if audio of a particular frequency is being produced.
        @param sample_width: The recorded sample width.
        @param sample_rate: The recorded sample rate.
        @param num_channels: The number of recorded channels.
        @param frequency: Frequency of audio being produced.
        """
        req = sequenced_request.SequencedFeedbackRequest(
            self.test, self.dut, 'Audio recording')
        # TODO(ralphnathan) Lift the restriction regarding recording time once
        # the test allows recording for arbitrary periods of time (b/26924426).
        req.append_question(
            'Device %(dut)s will start recording audio for 10 seconds. '
            'Please prepare for producing sound and hit Enter to '
            'continue...', input_handlers.PauseInputHandler())
        self._process_request(req)
        self._sample_width = sample_width
        self._sample_rate = sample_rate
        self._num_channels = num_channels
        if use_file:
            self._frequency = frequency
        else:
            self._frequency = None
    def _validate_impl(self, audio_file=None):
        """Validate playback (interface override).

        @param audio_file: Name of audio file on the test host to validate
                           against.
        """
        req = sequenced_request.SequencedFeedbackRequest(
            self.test, self.dut, None)
        msg = 'Playback finished on %(dut)s.'
        if audio_file is None:
            req.append_question(msg,
                                input_handlers.YesNoInputHandler(default=True),
                                prompt='Did you hear audible sound?')
            err_msg = 'User did not hear audible feedback'
        else:
            if not self._playback_wav_file(msg, audio_file):
                return (tester_feedback_client.QUERY_RET_ERROR,
                        'Failed to playback recorded audio')
            req.append_question(
                None,
                input_handlers.YesNoInputHandler(default=True),
                prompt=('Was the audio produced identical to the refernce '
                        'audio file?'))
            err_msg = ('Audio produced was not identical to the reference '
                       'audio file')

        if not self._process_request(req):
            return (tester_feedback_client.QUERY_RET_FAIL, err_msg)
    def _playback_wav_file(self, msg, audio_file):
        """Plays a WAV file via user selected method.

        Looks for available playback commands and presents them to the user to
        choose from. Also lists "manual playback" as the last option.

        @param msg: Introductory message to present to the user.
        @param audio_file: The audio file to play.

        @return: Whether playback was successful.
        """
        choices = []
        cmds = []
        for tool, cmd in _KNOWN_WAV_PLAYBACK_METHODS:
            if site_utils.which(tool):
                choices.append(tool)
                cmds.append(cmd)
        choices.append('Manual playback')

        msg += (' The audio file is %s. Available playback methods include:' %
                audio_file)
        req = sequenced_request.SequencedFeedbackRequest(
            self.test, self.dut, None)
        req.append_question(msg,
                            input_handlers.MultipleChoiceInputHandler(
                                choices, default=1),
                            prompt='Choose your playback method')
        idx, _ = self._process_request(req)
        if idx < len(choices) - 1:
            cmd = [tok % {'file': audio_file} for tok in cmds[idx]]
            return subprocess.call(cmd) == 0

        return True
 def _emit_impl(self):
     """Emit sound for recording (interface override)."""
     req = sequenced_request.SequencedFeedbackRequest(
         self.test, self.dut, None)
     req.append_question(
         'Device %(dut)s is recording audio, hit Enter when done '
         'producing sound...', input_handlers.PauseInputHandler())
     self._process_request(req)
 def _prepare_impl(self, **kwargs):
     """Prepare for audio playback (interface override)."""
     req = sequenced_request.SequencedFeedbackRequest(
         self.test, self.dut, 'Audible playback')
     req.append_question(
         'Device %(dut)s will play a short audible sample. Please '
         'prepare for listening to this playback and hit Enter to '
         'continue...', input_handlers.PauseInputHandler())
     self._process_request(req)
 def _prepare_impl(self):
     """Prepare for silent playback (interface override)."""
     req = sequenced_request.SequencedFeedbackRequest(
         self.test, self.dut, 'Silent playback')
     req.append_question(
         'Device %(dut)s will play nothing for a short time. Please '
         'prepare for listening to this silence and hit Enter to '
         'continue...', input_handlers.PauseInputHandler())
     self._process_request(req)
 def _prepare_impl(self):
     """Prepare for audio recording (interface override)."""
     req = sequenced_request.SequencedFeedbackRequest(
         self.test, self.dut, 'Audio recording')
     # TODO(ralphnathan) Lift the restriction regarding recording time once
     # the test allows recording for arbitrary periods of time (b/26924426).
     req.append_question(
         'Device %(dut)s will start recording audio for 10 seconds. '
         'Please prepare for producing sound and hit Enter to '
         'continue...', input_handlers.PauseInputHandler())
     self._process_request(req)
    def _validate_impl(self,
                       captured_audio_file,
                       sample_width,
                       sample_rate=None,
                       num_channels=None,
                       peak_percent_min=1,
                       peak_percent_max=100):
        """Validate recording (interface override).

        @param captured_audio_file: Path to the recorded WAV file.
        @param sample_width: The recorded sample width.
        @param sample_rate: The recorded sample rate.
        @param num_channels: The number of recorded channels.
        @peak_percent_min: Lower bound on peak recorded volume as percentage of
                           max molume (0-100). Default is 1%.
        @peak_percent_max: Upper bound on peak recorded volume as percentage of
                           max molume (0-100). Default is 100% (no limit).
        """
        # Check the WAV file properties first.
        try:
            site_utils.check_wav_file(captured_audio_file,
                                      num_channels=num_channels,
                                      sample_rate=sample_rate,
                                      sample_width=sample_width)
        except ValueError as e:
            return (tester_feedback_client.QUERY_RET_FAIL,
                    'Recorded audio file is invalid: %s' % e)

        # Verify playback of the recorded audio.
        props = ['has sample width of %d' % sample_width]
        if sample_rate is not None:
            props.append('has sample rate of %d' % sample_rate)
        if num_channels is not None:
            props.append('has %d recorded channels' % num_channels)
        props_str = '%s%s%s' % (', '.join(
            props[:-1]), ', and ' if len(props) > 1 else '', props[-1])

        msg = 'Recording finished on %%(dut)s. It %s.' % props_str
        if not self._playback_wav_file(msg, captured_audio_file):
            return (tester_feedback_client.QUERY_RET_ERROR,
                    'Failed to playback recorded audio')

        req = sequenced_request.SequencedFeedbackRequest(
            self.test, self.dut, None)
        req.append_question(
            None,
            input_handlers.YesNoInputHandler(default=True),
            prompt='Did the recording capture the sound produced?')
        if not self._process_request(req):
            return (
                tester_feedback_client.QUERY_RET_FAIL,
                'Recorded audio is not identical to what the user produced')
    def _validate_impl(self, audio_file=None):
        """Validate silence (interface override).

        @param audio_file: Name of audio file on the test host to validate
                           against.
        """
        if audio_file is not None:
            return (
                tester_feedback_client.QUERY_RET_ERROR,
                'Not expecting an audio file entry when validating silence')
        req = sequenced_request.SequencedFeedbackRequest(
            self.test, self.dut, None)
        req.append_question('Silence playback finished on %(dut)s.',
                            input_handlers.YesNoInputHandler(default=True),
                            prompt='Did you hear silence?')
        if not self._process_request(req):
            return (tester_feedback_client.QUERY_RET_FAIL,
                    'User did not hear silence')
    def _validate_impl(self, captured_audio_file):
        """Validate recording (interface override).

        @param captured_audio_file: Path to the recorded WAV file.
        """
        # Check the WAV file properties first.
        try:
            audio_utils.check_wav_file(captured_audio_file,
                                       num_channels=self._num_channels,
                                       sample_rate=self._sample_rate,
                                       sample_width=self._sample_width)
        except ValueError as e:
            return (tester_feedback_client.QUERY_RET_FAIL,
                    'Recorded audio file is invalid: %s' % e)

        # Verify playback of the recorded audio.
        props = [
            'as sample width of %d' % self._sample_width,
            'has sample rate of %d' % self._sample_rate,
            'has %d recorded channels' % self._num_channels
        ]
        if self._frequency is not None:
            props.append('has frequency of %d Hz' % self._frequency)
        props_str = '%s%s%s' % (', '.join(
            props[:-1]), ', and ' if len(props) > 1 else '', props[-1])

        msg = 'Recording finished on %%(dut)s. It %s.' % props_str
        if not self._playback_wav_file(msg, captured_audio_file):
            return (tester_feedback_client.QUERY_RET_ERROR,
                    'Failed to playback recorded audio')

        req = sequenced_request.SequencedFeedbackRequest(
            self.test, self.dut, None)
        req.append_question(
            None,
            input_handlers.YesNoInputHandler(default=True),
            prompt='Did the recording capture the sound produced?')
        if not self._process_request(req):
            return (
                tester_feedback_client.QUERY_RET_FAIL,
                'Recorded audio is not identical to what the user produced')
Exemplo n.º 11
0
    def _handle_requests(self, stdin):
        """Processes feedback requests until termination is signaled.

        This method is run in a separate process and needs to override stdin in
        order for raw_input() to work.
        """
        sys.stdin = stdin
        try:
            while True:
                req_idx = None

                # Wait for a (suitable) request to become available.
                while True:
                    if self._atomic_seq is None:
                        if self._pending:
                            break
                    else:
                        req_idx = self._atomic_seq_cont()
                        if req_idx is not None:
                            break
                    self._dequeue_request(block=True)

                # If no request was pre-selected, prompt the user to choose one.
                if req_idx is None:
                    raw_input('Pending feedback requests, hit Enter to '
                              'process... ')

                    # Pull all remaining queued requests.
                    while self._dequeue_request():
                        pass

                    # Select the request to process.
                    if len(self._pending) == 1:
                        print('Processing: %s' %
                              self._pending[0].obj.get_title())
                        req_idx = 0
                    else:
                        choose_req = sequenced_request.SequencedFeedbackRequest(
                            None, None, None)
                        choose_req.append_question(
                            'List of pending feedback requests:',
                            input_handlers.MultipleChoiceInputHandler(
                                [
                                    req_tuple.obj.get_title()
                                    for req_tuple in self._pending
                                ],
                                default=1),
                            prompt='Choose a request to process')
                        req_idx, _ = choose_req.execute()

                # Pop and handle selected request, then close pipe.
                req_tuple = self._pending.pop(req_idx)
                if req_tuple.obj is not None:
                    try:
                        ret = req_tuple.obj.execute()
                    except request.FeedbackRequestError as e:
                        ret = (tester_feedback_client.QUERY_RET_ERROR, str(e))
                    reply_pipe = req_tuple.reduced_reply_pipe[0](
                        *req_tuple.reduced_reply_pipe[1])
                    reply_pipe.send(ret)
                    reply_pipe.close()

                # Set the atomic sequence if so instructed.
                self._atomic_seq = (req_tuple.query_num
                                    if req_tuple.atomic else None)

        except self.RequestProcessingTerminated:
            pass