/*
 *  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 <list>
#include <memory>
#include <string>

#include "api/audio/audio_frame.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
#include "modules/audio_coding/neteq/include/neteq.h"
#include "modules/audio_coding/neteq/tools/input_audio_file.h"
#include "modules/audio_coding/neteq/tools/rtp_generator.h"
#include "rtc_base/strings/string_builder.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_),
        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_;
    rtc::scoped_refptr<AudioDecoderFactory> factory =
        CreateBuiltinAudioDecoderFactory();
    neteq_mono_ = NetEq::Create(config, factory);
    neteq_ = NetEq::Create(config, 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() {
    delete neteq_mono_;
    delete neteq_;
    delete[] input_;
    delete[] encoded_;
    delete[] input_multi_channel_;
    delete[] encoded_multi_channel_;
  }

  virtual void SetUp() {
    const std::string file_name =
        webrtc::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_)));
  }

  virtual void TearDown() {}

  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 = rtp_generator_mono_.GetRtpHeader(
        kPayloadTypeMono, frame_size_samples_, &rtp_header_mono_);
    test::InputAudioFile::DuplicateInterleaved(
        input_, frame_size_samples_, num_channels_, input_multi_channel_);
    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;
  }

  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;
    int next_arrival_time;
    do {
      next_send_time = GetNewPackets();
      ASSERT_NE(-1, next_send_time);
      next_arrival_time = GetArrivalTime(next_send_time);
    } while (Lost());  // If lost, immediately read the next packet.

    int time_now = 0;
    for (int k = 0; k < num_loops; ++k) {
      while (time_now >= next_arrival_time) {
        // Insert packet in mono instance.
        ASSERT_EQ(NetEq::kOK,
                  neteq_mono_->InsertPacket(rtp_header_mono_,
                                            rtc::ArrayView<const uint8_t>(
                                                encoded_, payload_size_bytes_),
                                            next_arrival_time));
        // Insert packet in multi-channel instance.
        ASSERT_EQ(NetEq::kOK,
                  neteq_->InsertPacket(
                      rtp_header_,
                      rtc::ArrayView<const uint8_t>(encoded_multi_channel_,
                                                    multi_payload_size_bytes_),
                      next_arrival_time));
        // Get next input packets (mono and multi-channel).
        do {
          next_send_time = GetNewPackets();
          ASSERT_NE(-1, next_send_time);
          next_arrival_time = GetArrivalTime(next_send_time);
        } 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_);
      rtc::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 += 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_;
  NetEq* neteq_mono_;
  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;
  }
  virtual int GetArrivalTime(int send_time) {
    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) {}

  virtual int GetArrivalTime(int send_time) {
    // 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) {}

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

  // TODO(hlundin): NetEq is not giving bitexact results for these cases.
  virtual void VerifyOutput(size_t num_samples) {
    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);
}

// 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()));

}  // namespace webrtc
