/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// Test to verify correct stereo and multi-channel operation.

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <list>
#include <memory>
#include <ostream>
#include <string>

#include "api/array_view.h"
#include "api/audio/audio_frame.h"
#include "api/audio_codecs/audio_format.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/neteq/default_neteq_factory.h"
#include "api/neteq/neteq.h"
#include "api/rtp_headers.h"
#include "api/units/timestamp.h"
#include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
#include "modules/audio_coding/neteq/tools/input_audio_file.h"
#include "modules/audio_coding/neteq/tools/rtp_generator.h"
#include "rtc_base/checks.h"
#include "rtc_base/strings/string_builder.h"
#include "system_wrappers/include/clock.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

namespace webrtc {

struct TestParameters {
  int frame_size;
  int sample_rate;
  size_t num_channels;
};

// This is a parameterized test. The test parameters are supplied through a
// TestParameters struct, which is obtained through the GetParam() method.
//
// The objective of the test is to create a mono input signal and a
// multi-channel input signal, where each channel is identical to the mono
// input channel. The two input signals are processed through their respective
// NetEq instances. After that, the output signals are compared. The expected
// result is that each channel in the multi-channel output is identical to the
// mono output.
class NetEqStereoTest : public ::testing::TestWithParam<TestParameters> {
 protected:
  static const int kTimeStepMs = 10;
  static const size_t kMaxBlockSize = 480;  // 10 ms @ 48 kHz.
  static const uint8_t kPayloadTypeMono = 95;
  static const uint8_t kPayloadTypeMulti = 96;

  NetEqStereoTest()
      : num_channels_(GetParam().num_channels),
        sample_rate_hz_(GetParam().sample_rate),
        samples_per_ms_(sample_rate_hz_ / 1000),
        frame_size_ms_(GetParam().frame_size),
        frame_size_samples_(
            static_cast<size_t>(frame_size_ms_ * samples_per_ms_)),
        output_size_samples_(10 * samples_per_ms_),
        clock_(0),
        env_(CreateEnvironment(&clock_)),
        rtp_generator_mono_(samples_per_ms_),
        rtp_generator_(samples_per_ms_),
        payload_size_bytes_(0),
        multi_payload_size_bytes_(0),
        last_send_time_(0),
        last_arrival_time_(0) {
    NetEq::Config config;
    config.sample_rate_hz = sample_rate_hz_;
    DefaultNetEqFactory neteq_factory;
    auto decoder_factory = CreateBuiltinAudioDecoderFactory();
    neteq_mono_ = neteq_factory.Create(env_, config, decoder_factory);
    neteq_ = neteq_factory.Create(env_, config, decoder_factory);
    input_ = new int16_t[frame_size_samples_];
    encoded_ = new uint8_t[2 * frame_size_samples_];
    input_multi_channel_ = new int16_t[frame_size_samples_ * num_channels_];
    encoded_multi_channel_ =
        new uint8_t[frame_size_samples_ * 2 * num_channels_];
  }

  ~NetEqStereoTest() override {
    delete[] input_;
    delete[] encoded_;
    delete[] input_multi_channel_;
    delete[] encoded_multi_channel_;
  }

  void SetUp() override {
    const std::string file_name =
        test::ResourcePath("audio_coding/testfile32kHz", "pcm");
    input_file_.reset(new test::InputAudioFile(file_name));
    RTC_CHECK_GE(num_channels_, 2);
    ASSERT_TRUE(neteq_mono_->RegisterPayloadType(
        kPayloadTypeMono, SdpAudioFormat("l16", sample_rate_hz_, 1)));
    ASSERT_TRUE(neteq_->RegisterPayloadType(
        kPayloadTypeMulti,
        SdpAudioFormat("l16", sample_rate_hz_, num_channels_)));
  }

  void TearDown() override {}

  int GetNewPackets() {
    if (!input_file_->Read(frame_size_samples_, input_)) {
      return -1;
    }
    payload_size_bytes_ =
        WebRtcPcm16b_Encode(input_, frame_size_samples_, encoded_);
    if (frame_size_samples_ * 2 != payload_size_bytes_) {
      return -1;
    }
    int next_send_time_ms = rtp_generator_mono_.GetRtpHeader(
        kPayloadTypeMono, frame_size_samples_, &rtp_header_mono_);
    MakeMultiChannelInput();
    multi_payload_size_bytes_ = WebRtcPcm16b_Encode(
        input_multi_channel_, frame_size_samples_ * num_channels_,
        encoded_multi_channel_);
    if (frame_size_samples_ * 2 * num_channels_ != multi_payload_size_bytes_) {
      return -1;
    }
    rtp_generator_.GetRtpHeader(kPayloadTypeMulti, frame_size_samples_,
                                &rtp_header_);
    return next_send_time_ms;
  }

  virtual void MakeMultiChannelInput() {
    test::InputAudioFile::DuplicateInterleaved(
        input_, frame_size_samples_, num_channels_, input_multi_channel_);
  }

  virtual void VerifyOutput(size_t num_samples) {
    const int16_t* output_data = output_.data();
    const int16_t* output_multi_channel_data = output_multi_channel_.data();
    for (size_t i = 0; i < num_samples; ++i) {
      for (size_t j = 0; j < num_channels_; ++j) {
        ASSERT_EQ(output_data[i],
                  output_multi_channel_data[i * num_channels_ + j])
            << "Diff in sample " << i << ", channel " << j << ".";
      }
    }
  }

  virtual int GetArrivalTime(int send_time) {
    int arrival_time = last_arrival_time_ + (send_time - last_send_time_);
    last_send_time_ = send_time;
    last_arrival_time_ = arrival_time;
    return arrival_time;
  }

  virtual bool Lost() { return false; }

  void RunTest(int num_loops) {
    // Get next input packets (mono and multi-channel).
    int next_send_time_ms;
    int next_arrival_time_ms;
    do {
      next_send_time_ms = GetNewPackets();
      ASSERT_NE(-1, next_send_time_ms);
      next_arrival_time_ms = GetArrivalTime(next_send_time_ms);
    } while (Lost());  // If lost, immediately read the next packet.

    int time_now_ms = 0;
    for (int k = 0; k < num_loops; ++k) {
      while (time_now_ms >= next_arrival_time_ms) {
        // Insert packet in mono instance.
        ASSERT_EQ(NetEq::kOK,
                  neteq_mono_->InsertPacket(
                      rtp_header_mono_,
                      ArrayView<const uint8_t>(encoded_, payload_size_bytes_),
                      Timestamp::Millis(time_now_ms)));
        // Insert packet in multi-channel instance.
        ASSERT_EQ(NetEq::kOK,
                  neteq_->InsertPacket(
                      rtp_header_,
                      ArrayView<const uint8_t>(encoded_multi_channel_,
                                               multi_payload_size_bytes_),
                      Timestamp::Millis(time_now_ms)));
        // Get next input packets (mono and multi-channel).
        do {
          next_send_time_ms = GetNewPackets();
          ASSERT_NE(-1, next_send_time_ms);
          next_arrival_time_ms = GetArrivalTime(next_send_time_ms);
        } while (Lost());  // If lost, immediately read the next packet.
      }
      // Get audio from mono instance.
      bool muted;
      EXPECT_EQ(NetEq::kOK, neteq_mono_->GetAudio(&output_, &muted));
      ASSERT_FALSE(muted);
      EXPECT_EQ(1u, output_.num_channels_);
      EXPECT_EQ(output_size_samples_, output_.samples_per_channel_);
      // Get audio from multi-channel instance.
      ASSERT_EQ(NetEq::kOK, neteq_->GetAudio(&output_multi_channel_, &muted));
      ASSERT_FALSE(muted);
      EXPECT_EQ(num_channels_, output_multi_channel_.num_channels_);
      EXPECT_EQ(output_size_samples_,
                output_multi_channel_.samples_per_channel_);
      StringBuilder ss;
      ss << "Lap number " << k << ".";
      SCOPED_TRACE(ss.str());  // Print out the parameter values on failure.
      // Compare mono and multi-channel.
      ASSERT_NO_FATAL_FAILURE(VerifyOutput(output_size_samples_));

      time_now_ms += kTimeStepMs;
      clock_.AdvanceTimeMilliseconds(kTimeStepMs);
    }
  }

  const size_t num_channels_;
  const int sample_rate_hz_;
  const int samples_per_ms_;
  const int frame_size_ms_;
  const size_t frame_size_samples_;
  const size_t output_size_samples_;
  SimulatedClock clock_;
  const Environment env_;
  std::unique_ptr<NetEq> neteq_mono_;
  std::unique_ptr<NetEq> neteq_;
  test::RtpGenerator rtp_generator_mono_;
  test::RtpGenerator rtp_generator_;
  int16_t* input_;
  int16_t* input_multi_channel_;
  uint8_t* encoded_;
  uint8_t* encoded_multi_channel_;
  AudioFrame output_;
  AudioFrame output_multi_channel_;
  RTPHeader rtp_header_mono_;
  RTPHeader rtp_header_;
  size_t payload_size_bytes_;
  size_t multi_payload_size_bytes_;
  int last_send_time_;
  int last_arrival_time_;
  std::unique_ptr<test::InputAudioFile> input_file_;
};

class NetEqStereoTestNoJitter : public NetEqStereoTest {
 protected:
  NetEqStereoTestNoJitter() : NetEqStereoTest() {
    // Start the sender 100 ms before the receiver to pre-fill the buffer.
    // This is to avoid doing preemptive expand early in the test.
    // TODO(hlundin): Mock the decision making instead to control the modes.
    last_arrival_time_ = -100;
  }
};

TEST_P(NetEqStereoTestNoJitter, RunTest) {
  RunTest(8);
}

class NetEqStereoTestPositiveDrift : public NetEqStereoTest {
 protected:
  NetEqStereoTestPositiveDrift() : NetEqStereoTest(), drift_factor(0.9) {
    // Start the sender 100 ms before the receiver to pre-fill the buffer.
    // This is to avoid doing preemptive expand early in the test.
    // TODO(hlundin): Mock the decision making instead to control the modes.
    last_arrival_time_ = -100;
  }
  int GetArrivalTime(int send_time) override {
    int arrival_time =
        last_arrival_time_ + drift_factor * (send_time - last_send_time_);
    last_send_time_ = send_time;
    last_arrival_time_ = arrival_time;
    return arrival_time;
  }

  double drift_factor;
};

TEST_P(NetEqStereoTestPositiveDrift, RunTest) {
  RunTest(100);
}

class NetEqStereoTestNegativeDrift : public NetEqStereoTestPositiveDrift {
 protected:
  NetEqStereoTestNegativeDrift() : NetEqStereoTestPositiveDrift() {
    drift_factor = 1.1;
    last_arrival_time_ = 0;
  }
};

TEST_P(NetEqStereoTestNegativeDrift, RunTest) {
  RunTest(100);
}

class NetEqStereoTestDelays : public NetEqStereoTest {
 protected:
  static const int kDelayInterval = 10;
  static const int kDelay = 1000;
  NetEqStereoTestDelays() : NetEqStereoTest(), frame_index_(0) {}

  int GetArrivalTime(int send_time) override {
    // Deliver immediately, unless we have a back-log.
    int arrival_time = std::min(last_arrival_time_, send_time);
    if (++frame_index_ % kDelayInterval == 0) {
      // Delay this packet.
      arrival_time += kDelay;
    }
    last_send_time_ = send_time;
    last_arrival_time_ = arrival_time;
    return arrival_time;
  }

  int frame_index_;
};

TEST_P(NetEqStereoTestDelays, RunTest) {
  RunTest(1000);
}

class NetEqStereoTestLosses : public NetEqStereoTest {
 protected:
  static const int kLossInterval = 10;
  NetEqStereoTestLosses() : NetEqStereoTest(), frame_index_(0) {}

  bool Lost() override { return (++frame_index_) % kLossInterval == 0; }

  // TODO(hlundin): NetEq is not giving bitexact results for these cases.
  void VerifyOutput(size_t num_samples) override {
    for (size_t i = 0; i < num_samples; ++i) {
      const int16_t* output_data = output_.data();
      const int16_t* output_multi_channel_data = output_multi_channel_.data();
      auto first_channel_sample = output_multi_channel_data[i * num_channels_];
      for (size_t j = 0; j < num_channels_; ++j) {
        const int kErrorMargin = 200;
        EXPECT_NEAR(output_data[i],
                    output_multi_channel_data[i * num_channels_ + j],
                    kErrorMargin)
            << "Diff in sample " << i << ", channel " << j << ".";
        EXPECT_EQ(first_channel_sample,
                  output_multi_channel_data[i * num_channels_ + j]);
      }
    }
  }

  int frame_index_;
};

TEST_P(NetEqStereoTestLosses, RunTest) {
  RunTest(100);
}

class NetEqStereoTestSingleActiveChannelPlc : public NetEqStereoTestLosses {
 protected:
  NetEqStereoTestSingleActiveChannelPlc() : NetEqStereoTestLosses() {}

  void MakeMultiChannelInput() override {
    // Create a multi-channel input by copying the mono channel from file to the
    // first channel, and setting the others to zero.
    memset(input_multi_channel_, 0,
           frame_size_samples_ * num_channels_ * sizeof(int16_t));
    for (size_t i = 0; i < frame_size_samples_; ++i) {
      input_multi_channel_[i * num_channels_] = input_[i];
    }
  }

  void VerifyOutput(size_t num_samples) override {
    // Simply verify that all samples in channels other than the first are zero.
    const int16_t* output_multi_channel_data = output_multi_channel_.data();
    for (size_t i = 0; i < num_samples; ++i) {
      for (size_t j = 1; j < num_channels_; ++j) {
        EXPECT_EQ(0, output_multi_channel_data[i * num_channels_ + j])
            << "Sample " << i << ", channel " << j << " is non-zero.";
      }
    }
  }
};

TEST_P(NetEqStereoTestSingleActiveChannelPlc, RunTest) {
  RunTest(100);
}

// Creates a list of parameter sets.
std::list<TestParameters> GetTestParameters() {
  std::list<TestParameters> l;
  const int sample_rates[] = {8000, 16000, 32000};
  const int num_rates = sizeof(sample_rates) / sizeof(sample_rates[0]);
  // Loop through sample rates.
  for (int rate_index = 0; rate_index < num_rates; ++rate_index) {
    int sample_rate = sample_rates[rate_index];
    // Loop through all frame sizes between 10 and 60 ms.
    for (int frame_size = 10; frame_size <= 60; frame_size += 10) {
      TestParameters p;
      p.frame_size = frame_size;
      p.sample_rate = sample_rate;
      p.num_channels = 2;
      l.push_back(p);
      if (sample_rate == 8000) {
        // Add a five-channel test for 8000 Hz.
        p.num_channels = 5;
        l.push_back(p);
      }
    }
  }
  return l;
}

// Pretty-printing the test parameters in case of an error.
void PrintTo(const TestParameters& p, ::std::ostream* os) {
  *os << "{frame_size = " << p.frame_size
      << ", num_channels = " << p.num_channels
      << ", sample_rate = " << p.sample_rate << "}";
}

// Instantiate the tests. Each test is instantiated using the function above,
// so that all different parameter combinations are tested.
INSTANTIATE_TEST_SUITE_P(MultiChannel,
                         NetEqStereoTestNoJitter,
                         ::testing::ValuesIn(GetTestParameters()));

INSTANTIATE_TEST_SUITE_P(MultiChannel,
                         NetEqStereoTestPositiveDrift,
                         ::testing::ValuesIn(GetTestParameters()));

INSTANTIATE_TEST_SUITE_P(MultiChannel,
                         NetEqStereoTestNegativeDrift,
                         ::testing::ValuesIn(GetTestParameters()));

INSTANTIATE_TEST_SUITE_P(MultiChannel,
                         NetEqStereoTestDelays,
                         ::testing::ValuesIn(GetTestParameters()));

INSTANTIATE_TEST_SUITE_P(MultiChannel,
                         NetEqStereoTestLosses,
                         ::testing::ValuesIn(GetTestParameters()));

INSTANTIATE_TEST_SUITE_P(MultiChannel,
                         NetEqStereoTestSingleActiveChannelPlc,
                         ::testing::ValuesIn(GetTestParameters()));
}  // namespace webrtc
