# Lint as: python2, python3
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""This is a server side pinned stream audio test using the Chameleon board."""

import logging
import os
import time

from autotest_lib.client.cros.audio import audio_test_data
from autotest_lib.client.cros.chameleon import audio_test_utils
from autotest_lib.client.cros.chameleon import chameleon_audio_ids
from autotest_lib.client.cros.chameleon import chameleon_audio_helper
from autotest_lib.server.cros.audio import audio_test


class audio_AudioPinnedStream(audio_test.AudioTest):
    """Server side pinned stream audio test.

    This test talks to a Chameleon board and a Cros device to verify
    pinned stream audio function of the Cros device.

    """
    version = 1
    DELAY_BEFORE_RECORD_SECONDS = 0.5
    PLAYBACK_RECORD_SECONDS = 3
    RECORDING_RECORD_SECONDS = 6
    DELAY_AFTER_BINDING = 0.5

    def run_once(self, playback):
        """Running basic pinned stream audio tests.

        @param playback: True if testing for playback path
        """
        # [1330, 1330] sine wave
        golden_file = audio_test_data.GenerateAudioTestData(
                path=os.path.join(self.bindir, 'fix_1330_16.raw'),
                duration_secs=10,
                frequencies=[1330, 1330],
                volume_scale=0.1)

        # [2000, 1000] sine wave
        usb_golden_file = audio_test_data.GenerateAudioTestData(
                path=os.path.join(self.bindir, 'fix_2k_1k_16.raw'),
                duration_secs=10,
                frequencies=[2000, 1000])

        if playback:
            source = self.widget_factory.create_widget(
                    chameleon_audio_ids.CrosIds.HEADPHONE)
            recorder = self.widget_factory.create_widget(
                    chameleon_audio_ids.ChameleonIds.LINEIN)
            usb_source = self.widget_factory.create_widget(
                    chameleon_audio_ids.CrosIds.USBOUT)
            usb_recorder = self.widget_factory.create_widget(
                    chameleon_audio_ids.ChameleonIds.USBIN)
        else:
            source = self.widget_factory.create_widget(
                    chameleon_audio_ids.ChameleonIds.LINEOUT)
            recorder = self.widget_factory.create_widget(
                    chameleon_audio_ids.CrosIds.EXTERNAL_MIC)
            usb_source = self.widget_factory.create_widget(
                    chameleon_audio_ids.ChameleonIds.USBOUT)
            usb_recorder = self.widget_factory.create_widget(
                    chameleon_audio_ids.CrosIds.USBIN)

        binder = self.widget_factory.create_binder(source, recorder)
        usb_binder = self.widget_factory.create_binder(usb_source,
                                                       usb_recorder)

        with chameleon_audio_helper.bind_widgets(usb_binder):
            with chameleon_audio_helper.bind_widgets(binder):
                time.sleep(self.DELAY_AFTER_BINDING)

                if playback:
                    audio_test_utils.check_and_set_chrome_active_node_types(
                            self.facade, 'HEADPHONE', None)
                else:
                    audio_test_utils.check_and_set_chrome_active_node_types(
                            self.facade, None, 'MIC')

                logging.info('Setting playback data')
                source.set_playback_data(golden_file)
                usb_source.set_playback_data(usb_golden_file)

                logging.info('Start playing %s', golden_file.path)
                source.start_playback()

                logging.info('Start playing %s, pinned:%s',
                             usb_golden_file.path, playback)
                usb_source.start_playback(pinned=playback)

                time.sleep(self.DELAY_BEFORE_RECORD_SECONDS)

                logging.info('Start recording.')
                recorder.start_recording()
                if playback:
                    # Not any two recorders on chameleon can record at the same
                    # time. USB and LineIn can but we would keep them separate
                    # here to keep things simple and change it when needed.
                    # Should still record [2000, 1000] sine wave from USB as
                    # it was set pinned on USB.
                    time.sleep(self.PLAYBACK_RECORD_SECONDS)
                    recorder.stop_recording()
                    usb_recorder.start_recording()
                    time.sleep(self.PLAYBACK_RECORD_SECONDS)
                    usb_recorder.stop_recording()
                else:
                    usb_recorder.start_recording(pinned=True)
                    time.sleep(self.RECORDING_RECORD_SECONDS)
                    recorder.stop_recording()
                    usb_recorder.stop_recording(pinned=True)

                audio_test_utils.dump_cros_audio_logs(self.host, self.facade,
                                                      self.resultsdir,
                                                      'after_recording')

        recorder.read_recorded_binary()
        usb_recorder.read_recorded_binary()

        recorded_file = os.path.join(self.resultsdir, "recorded.raw")
        logging.info('Saving recorded data to %s', recorded_file)
        recorder.save_file(recorded_file)

        usb_recorded_file = os.path.join(self.resultsdir, "usb_recorded.raw")
        logging.info('Saving recorded data to %s', usb_recorded_file)
        usb_recorder.save_file(usb_recorded_file)

        if playback:
            audio_test_utils.check_recorded_frequency(golden_file, recorder)
        else:
            # The signal quality from chameleon will get affected when usb is
            # also connected. We'll just lower the quality bar here, as it is
            # not the main point of this test.
            audio_test_utils.check_recorded_frequency(
                    golden_file, recorder, second_peak_ratio=0.3)
        audio_test_utils.check_recorded_frequency(usb_golden_file,
                                                  usb_recorder)
