// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/audio/win/audio_low_latency_output_win.h"

#include <mmsystem.h>
#include <stddef.h>
#include <stdint.h>
#include <windows.h>

#include <memory>

#include "base/environment.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/task_environment.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/win/scoped_com_initializer.h"
#include "media/audio/audio_device_description.h"
#include "media/audio/audio_device_info_accessor_for_tests.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_manager.h"
#include "media/audio/audio_unittest_util.h"
#include "media/audio/mock_audio_source_callback.h"
#include "media/audio/test_audio_thread.h"
#include "media/audio/win/core_audio_util_win.h"
#include "media/base/decoder_buffer.h"
#include "media/base/seekable_buffer.h"
#include "media/base/test_data_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::base::ThreadTaskRunnerHandle;
using ::testing::_;
using ::testing::DoAll;
using ::testing::NotNull;
using ::testing::Return;

namespace media {

static const int kBitsPerSample = 16;
static const size_t kMaxDeltaSamples = 1000;
static const char kDeltaTimeMsFileName[] = "delta_times_ms.txt";

MATCHER_P(HasValidDelay, value, "") {
  // It is difficult to come up with a perfect test condition for the delay
  // estimation. For now, verify that the produced output delay is always
  // larger than the selected buffer size.
  return arg >= value;
}

// Used to terminate a loop from a different thread than the loop belongs to.
// |task_runner| should be a SingleThreadTaskRunner.
ACTION_P(QuitLoop, task_runner) {
  task_runner->PostTask(FROM_HERE,
                        base::RunLoop::QuitCurrentWhenIdleClosureDeprecated());
}

// This audio source implementation should be used for manual tests only since
// it takes about 20 seconds to play out a file.
class ReadFromFileAudioSource : public AudioOutputStream::AudioSourceCallback {
 public:
  explicit ReadFromFileAudioSource(const std::string& name)
      : pos_(0),
        previous_call_time_(base::TimeTicks::Now()),
        text_file_(nullptr),
        elements_to_write_(0) {
    // Reads a test file from media/test/data directory.
    file_ = ReadTestDataFile(name);

    // Creates an array that will store delta times between callbacks.
    // The content of this array will be written to a text file at
    // destruction and can then be used for off-line analysis of the exact
    // timing of callbacks. The text file will be stored in media/test/data.
    delta_times_.reset(new int[kMaxDeltaSamples]);
  }

  ~ReadFromFileAudioSource() override {
    // Get complete file path to output file in directory containing
    // media_unittests.exe.
    base::FilePath file_name;
    EXPECT_TRUE(base::PathService::Get(base::DIR_EXE, &file_name));
    file_name = file_name.AppendASCII(kDeltaTimeMsFileName);

    EXPECT_TRUE(!text_file_);
    text_file_ = base::OpenFile(file_name, "wt");
    DLOG_IF(ERROR, !text_file_) << "Failed to open log file.";

    // Write the array which contains delta times to a text file.
    size_t elements_written = 0;
    while (elements_written < elements_to_write_) {
      fprintf(text_file_, "%d\n", delta_times_[elements_written]);
      ++elements_written;
    }

    base::CloseFile(text_file_);
  }

  // AudioOutputStream::AudioSourceCallback implementation.
  int OnMoreData(base::TimeDelta /* delay */,
                 base::TimeTicks /* delay_timestamp */,
                 int /* prior_frames_skipped */,
                 AudioBus* dest) override {
    // Store time difference between two successive callbacks in an array.
    // These values will be written to a file in the destructor.
    const base::TimeTicks now_time = base::TimeTicks::Now();
    const int diff = (now_time - previous_call_time_).InMilliseconds();
    previous_call_time_ = now_time;
    if (elements_to_write_ < kMaxDeltaSamples) {
      delta_times_[elements_to_write_] = diff;
      ++elements_to_write_;
    }

    int max_size = dest->frames() * dest->channels() * kBitsPerSample / 8;

    // Use samples read from a data file and fill up the audio buffer
    // provided to us in the callback.
    if (pos_ + max_size > file_size())
      max_size = file_size() - pos_;
    int frames = max_size / (dest->channels() * kBitsPerSample / 8);
    if (max_size) {
      static_assert(kBitsPerSample == 16, "FromInterleaved expects 2 bytes.");
      dest->FromInterleaved<SignedInt16SampleTypeTraits>(
          reinterpret_cast<const int16_t*>(file_->data() + pos_), frames);
      pos_ += max_size;
    }
    return frames;
  }

  void OnError(ErrorType type) override {}

  int file_size() { return file_->data_size(); }

 private:
  scoped_refptr<DecoderBuffer> file_;
  std::unique_ptr<int[]> delta_times_;
  int pos_;
  base::TimeTicks previous_call_time_;
  FILE* text_file_;
  size_t elements_to_write_;
};

static bool ExclusiveModeIsEnabled() {
  return (WASAPIAudioOutputStream::GetShareMode() ==
          AUDCLNT_SHAREMODE_EXCLUSIVE);
}

static bool HasCoreAudioAndOutputDevices(AudioManager* audio_man) {
  // The low-latency (WASAPI-based) version requires Windows Vista or higher.
  // TODO(henrika): note that we use Wave today to query the number of
  // existing output devices.
  return CoreAudioUtil::IsSupported() &&
         AudioDeviceInfoAccessorForTests(audio_man).HasAudioOutputDevices();
}

// Convenience method which creates a default AudioOutputStream object but
// also allows the user to modify the default settings.
class AudioOutputStreamWrapper {
 public:
  explicit AudioOutputStreamWrapper(AudioManager* audio_manager)
      : audio_man_(audio_manager),
        format_(AudioParameters::AUDIO_PCM_LOW_LATENCY) {
    AudioParameters preferred_params;
    EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetPreferredAudioParameters(
        AudioDeviceDescription::kDefaultDeviceId, true, &preferred_params)));
    channels_ = preferred_params.channels();
    channel_layout_ = preferred_params.channel_layout();
    sample_rate_ = preferred_params.sample_rate();
    samples_per_packet_ = preferred_params.frames_per_buffer();
  }

  ~AudioOutputStreamWrapper() {}

  // Creates AudioOutputStream object using default parameters.
  AudioOutputStream* Create() { return CreateOutputStream(); }

  // Creates AudioOutputStream object using non-default parameters where the
  // frame size is modified.
  AudioOutputStream* Create(int samples_per_packet) {
    samples_per_packet_ = samples_per_packet;
    return CreateOutputStream();
  }

  // Creates AudioOutputStream object using non-default parameters where the
  // sample rate and frame size are modified.
  AudioOutputStream* Create(int sample_rate, int samples_per_packet) {
    sample_rate_ = sample_rate;
    samples_per_packet_ = samples_per_packet;
    return CreateOutputStream();
  }

  AudioParameters::Format format() const { return format_; }
  int channels() const { return channels_; }
  int sample_rate() const { return sample_rate_; }
  int samples_per_packet() const { return samples_per_packet_; }

 private:
  AudioOutputStream* CreateOutputStream() {
    AudioParameters params(format_, channel_layout_, sample_rate_,
                           samples_per_packet_);
    if (channel_layout_ == CHANNEL_LAYOUT_DISCRETE) {
      params.set_channels_for_discrete(channels_);
    }
    DVLOG(1) << params.AsHumanReadableString();
    AudioOutputStream* aos = audio_man_->MakeAudioOutputStream(
        params, std::string(), AudioManager::LogCallback());
    EXPECT_TRUE(aos);
    return aos;
  }

  AudioManager* audio_man_;
  AudioParameters::Format format_;
  int channels_;
  ChannelLayout channel_layout_;
  int sample_rate_;
  int samples_per_packet_;
};

// Convenience method which creates a default AudioOutputStream object.
static AudioOutputStream* CreateDefaultAudioOutputStream(
    AudioManager* audio_manager) {
  AudioOutputStreamWrapper aosw(audio_manager);
  AudioOutputStream* aos = aosw.Create();
  return aos;
}

class WASAPIAudioOutputStreamTest : public ::testing::Test {
 public:
  WASAPIAudioOutputStreamTest() {
    audio_manager_ =
        AudioManager::CreateForTesting(std::make_unique<TestAudioThread>());
    base::RunLoop().RunUntilIdle();
  }
  ~WASAPIAudioOutputStreamTest() override { audio_manager_->Shutdown(); }

 protected:
  base::test::SingleThreadTaskEnvironment task_environment_{
      base::test::SingleThreadTaskEnvironment::MainThreadType::UI};
  std::unique_ptr<AudioManager> audio_manager_;
};

// Test Create(), Close() calling sequence.
TEST_F(WASAPIAudioOutputStreamTest, CreateAndClose) {
  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
  aos->Close();
}

// Test Open(), Close() calling sequence.
TEST_F(WASAPIAudioOutputStreamTest, OpenAndClose) {
  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
  EXPECT_TRUE(aos->Open());
  aos->Close();
}

// Test Open(), Start(), Close() calling sequence.
TEST_F(WASAPIAudioOutputStreamTest, OpenStartAndClose) {
  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
  EXPECT_TRUE(aos->Open());
  MockAudioSourceCallback source;
  EXPECT_CALL(source, OnError(_)).Times(0);
  aos->Start(&source);
  aos->Close();
}

// Test Open(), Start(), Stop(), Close() calling sequence.
TEST_F(WASAPIAudioOutputStreamTest, OpenStartStopAndClose) {
  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
  EXPECT_TRUE(aos->Open());
  MockAudioSourceCallback source;
  EXPECT_CALL(source, OnError(_)).Times(0);
  aos->Start(&source);
  aos->Stop();
  aos->Close();
}

// Test SetVolume(), GetVolume()
TEST_F(WASAPIAudioOutputStreamTest, Volume) {
  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());

  // Initial volume should be full volume (1.0).
  double volume = 0.0;
  aos->GetVolume(&volume);
  EXPECT_EQ(1.0, volume);

  // Verify some valid volume settings.
  aos->SetVolume(0.0);
  aos->GetVolume(&volume);
  EXPECT_EQ(0.0, volume);

  aos->SetVolume(0.5);
  aos->GetVolume(&volume);
  EXPECT_EQ(0.5, volume);

  aos->SetVolume(1.0);
  aos->GetVolume(&volume);
  EXPECT_EQ(1.0, volume);

  // Ensure that invalid volume setting have no effect.
  aos->SetVolume(1.5);
  aos->GetVolume(&volume);
  EXPECT_EQ(1.0, volume);

  aos->SetVolume(-0.5);
  aos->GetVolume(&volume);
  EXPECT_EQ(1.0, volume);

  aos->Close();
}

// Test some additional calling sequences.
TEST_F(WASAPIAudioOutputStreamTest, MiscCallingSequences) {
  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));

  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
  WASAPIAudioOutputStream* waos = static_cast<WASAPIAudioOutputStream*>(aos);

  // Open(), Open() is a valid calling sequence (second call does nothing).
  EXPECT_TRUE(aos->Open());
  EXPECT_TRUE(aos->Open());

  MockAudioSourceCallback source;

  // Start(), Start() is a valid calling sequence (second call does nothing).
  aos->Start(&source);
  EXPECT_TRUE(waos->started());
  aos->Start(&source);
  EXPECT_TRUE(waos->started());

  // Stop(), Stop() is a valid calling sequence (second call does nothing).
  aos->Stop();
  EXPECT_FALSE(waos->started());
  aos->Stop();
  EXPECT_FALSE(waos->started());

  // Start(), Stop(), Start(), Stop().
  aos->Start(&source);
  EXPECT_TRUE(waos->started());
  aos->Stop();
  EXPECT_FALSE(waos->started());
  aos->Start(&source);
  EXPECT_TRUE(waos->started());
  aos->Stop();
  EXPECT_FALSE(waos->started());

  aos->Close();
}

// Use preferred packet size and verify that rendering starts.
TEST_F(WASAPIAudioOutputStreamTest, ValidPacketSize) {
  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));

  MockAudioSourceCallback source;
  // Create default WASAPI output stream which plays out in stereo using
  // the shared mixing rate. The default buffer size is 10ms.
  AudioOutputStreamWrapper aosw(audio_manager_.get());
  AudioOutputStream* aos = aosw.Create();
  EXPECT_TRUE(aos->Open());

  // Derive the expected duration of each packet.
  base::TimeDelta packet_duration = base::Seconds(
      static_cast<double>(aosw.samples_per_packet()) / aosw.sample_rate());

  // Wait for the first callback and verify its parameters.  Ignore any
  // subsequent callbacks that might arrive.
  EXPECT_CALL(source,
              OnMoreData(HasValidDelay(packet_duration), _, 0, NotNull()))
      .WillOnce(DoAll(QuitLoop(ThreadTaskRunnerHandle::Get()),
                      Return(aosw.samples_per_packet())))
      .WillRepeatedly(Return(0));

  aos->Start(&source);
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
      TestTimeouts::action_timeout());
  base::RunLoop().Run();
  aos->Stop();
  aos->Close();
}

// Verify that we can open the output stream in exclusive mode using a
// certain set of audio parameters and a sample rate of 48kHz.
// The expected outcomes of each setting in this test has been derived
// manually using log outputs (--v=1).
// It's disabled by default because a flag is required to enable exclusive mode.
TEST_F(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeBufferSizesAt48kHz) {
  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()) &&
                          ExclusiveModeIsEnabled());

  AudioOutputStreamWrapper aosw(audio_manager_.get());

  // 10ms @ 48kHz shall work.
  // Note that, this is the same size as we can use for shared-mode streaming
  // but here the endpoint buffer delay is only 10ms instead of 20ms.
  AudioOutputStream* aos = aosw.Create(48000, 480);
  EXPECT_TRUE(aos->Open());
  aos->Close();

  // 5ms @ 48kHz does not work due to misalignment.
  // This test will propose an aligned buffer size of 5.3333ms.
  // Note that we must call Close() even is Open() fails since Close() also
  // deletes the object and we want to create a new object in the next test.
  aos = aosw.Create(48000, 240);
  EXPECT_FALSE(aos->Open());
  aos->Close();

  // 5.3333ms @ 48kHz should work (see test above).
  aos = aosw.Create(48000, 256);
  EXPECT_TRUE(aos->Open());
  aos->Close();

  // 2.6667ms is smaller than the minimum supported size (=3ms).
  aos = aosw.Create(48000, 128);
  EXPECT_FALSE(aos->Open());
  aos->Close();

  // 3ms does not correspond to an aligned buffer size.
  // This test will propose an aligned buffer size of 3.3333ms.
  aos = aosw.Create(48000, 144);
  EXPECT_FALSE(aos->Open());
  aos->Close();

  // 3.3333ms @ 48kHz <=> smallest possible buffer size we can use.
  aos = aosw.Create(48000, 160);
  EXPECT_TRUE(aos->Open());
  aos->Close();
}

// Verify that we can open the output stream in exclusive mode using a
// certain set of audio parameters and a sample rate of 44.1kHz.
// The expected outcomes of each setting in this test has been derived
// manually using log outputs (--v=1).
// It's disabled by default because a flag is required to enable exclusive mode.
TEST_F(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeBufferSizesAt44kHz) {
  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()) &&
                          ExclusiveModeIsEnabled());

  AudioOutputStreamWrapper aosw(audio_manager_.get());

  // 10ms @ 44.1kHz does not work due to misalignment.
  // This test will propose an aligned buffer size of 10.1587ms.
  AudioOutputStream* aos = aosw.Create(44100, 441);
  EXPECT_FALSE(aos->Open());
  aos->Close();

  // 10.1587ms @ 44.1kHz shall work (see test above).
  aos = aosw.Create(44100, 448);
  EXPECT_TRUE(aos->Open());
  aos->Close();

  // 5.8050ms @ 44.1 should work.
  aos = aosw.Create(44100, 256);
  EXPECT_TRUE(aos->Open());
  aos->Close();

  // 4.9887ms @ 44.1kHz does not work to misalignment.
  // This test will propose an aligned buffer size of 5.0794ms.
  // Note that we must call Close() even is Open() fails since Close() also
  // deletes the object and we want to create a new object in the next test.
  aos = aosw.Create(44100, 220);
  EXPECT_FALSE(aos->Open());
  aos->Close();

  // 5.0794ms @ 44.1kHz shall work (see test above).
  aos = aosw.Create(44100, 224);
  EXPECT_TRUE(aos->Open());
  aos->Close();

  // 2.9025ms is smaller than the minimum supported size (=3ms).
  aos = aosw.Create(44100, 132);
  EXPECT_FALSE(aos->Open());
  aos->Close();

  // 3.01587ms is larger than the minimum size but is not aligned.
  // This test will propose an aligned buffer size of 3.6281ms.
  aos = aosw.Create(44100, 133);
  EXPECT_FALSE(aos->Open());
  aos->Close();

  // 3.6281ms @ 44.1kHz <=> smallest possible buffer size we can use.
  aos = aosw.Create(44100, 160);
  EXPECT_TRUE(aos->Open());
  aos->Close();
}

// Verify that we can open and start the output stream in exclusive mode at
// the lowest possible delay at 48kHz.
// It's disabled by default because a flag is required to enable exclusive mode.
TEST_F(WASAPIAudioOutputStreamTest,
       DISABLED_ExclusiveModeMinBufferSizeAt48kHz) {
  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()) &&
                          ExclusiveModeIsEnabled());

  MockAudioSourceCallback source;
  // Create exclusive-mode WASAPI output stream which plays out in stereo
  // using the minimum buffer size at 48kHz sample rate.
  AudioOutputStreamWrapper aosw(audio_manager_.get());
  AudioOutputStream* aos = aosw.Create(48000, 160);
  EXPECT_TRUE(aos->Open());

  // Derive the expected size in bytes of each packet.
  base::TimeDelta packet_duration = base::Seconds(
      static_cast<double>(aosw.samples_per_packet()) / aosw.sample_rate());

  // Wait for the first callback and verify its parameters.
  EXPECT_CALL(source,
              OnMoreData(HasValidDelay(packet_duration), _, 0, NotNull()))
      .WillOnce(DoAll(QuitLoop(ThreadTaskRunnerHandle::Get()),
                      Return(aosw.samples_per_packet())))
      .WillRepeatedly(Return(aosw.samples_per_packet()));

  aos->Start(&source);
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
      TestTimeouts::action_timeout());
  base::RunLoop().Run();
  aos->Stop();
  aos->Close();
}

// Verify that we can open and start the output stream in exclusive mode at
// the lowest possible delay at 44.1kHz.
// It's disabled by default because a flag is required to enable exclusive mode.
TEST_F(WASAPIAudioOutputStreamTest,
       DISABLED_ExclusiveModeMinBufferSizeAt44kHz) {
  ABORT_AUDIO_TEST_IF_NOT(ExclusiveModeIsEnabled());

  MockAudioSourceCallback source;
  // Create exclusive-mode WASAPI output stream which plays out in stereo
  // using the minimum buffer size at 44.1kHz sample rate.
  AudioOutputStreamWrapper aosw(audio_manager_.get());
  AudioOutputStream* aos = aosw.Create(44100, 160);
  EXPECT_TRUE(aos->Open());

  // Derive the expected size in bytes of each packet.
  base::TimeDelta packet_duration = base::Seconds(
      static_cast<double>(aosw.samples_per_packet()) / aosw.sample_rate());

  // Wait for the first callback and verify its parameters.
  EXPECT_CALL(source,
              OnMoreData(HasValidDelay(packet_duration), _, 0, NotNull()))
      .WillOnce(DoAll(QuitLoop(ThreadTaskRunnerHandle::Get()),
                      Return(aosw.samples_per_packet())))
      .WillRepeatedly(Return(aosw.samples_per_packet()));

  aos->Start(&source);
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
      TestTimeouts::action_timeout());
  base::RunLoop().Run();
  aos->Stop();
  aos->Close();
}

}  // namespace media
