/*
 *  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.
 */

#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h"

#include <assert.h>
#include <math.h>

#include <iostream>

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common_types.h"
#include "webrtc/engine_configurations.h"
#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h"
#include "webrtc/modules/audio_coding/main/test/Channel.h"
#include "webrtc/modules/audio_coding/main/test/PCMFile.h"
#include "webrtc/modules/audio_coding/main/test/utility.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/test/testsupport/gtest_disable.h"

namespace webrtc {

namespace {

double FrameRms(AudioFrame& frame) {
  size_t samples = frame.num_channels_ * frame.samples_per_channel_;
  double rms = 0;
  for (size_t n = 0; n < samples; ++n)
    rms += frame.data_[n] * frame.data_[n];
  rms /= samples;
  rms = sqrt(rms);
  return rms;
}

}

class InitialPlayoutDelayTest : public ::testing::Test {
 protected:
  InitialPlayoutDelayTest()
      : acm_a_(AudioCodingModule::Create(0)),
        acm_b_(AudioCodingModule::Create(1)),
        channel_a2b_(NULL) {}

  ~InitialPlayoutDelayTest() {
    if (channel_a2b_ != NULL) {
      delete channel_a2b_;
      channel_a2b_ = NULL;
    }
  }

  void SetUp() {
    ASSERT_TRUE(acm_a_.get() != NULL);
    ASSERT_TRUE(acm_b_.get() != NULL);

    EXPECT_EQ(0, acm_b_->InitializeReceiver());
    EXPECT_EQ(0, acm_a_->InitializeReceiver());

    // Register all L16 codecs in receiver.
    CodecInst codec;
    const int kFsHz[3] = { 8000, 16000, 32000 };
    const int kChannels[2] = { 1, 2 };
    for (int n = 0; n < 3; ++n) {
      for (int k = 0; k < 2; ++k) {
        AudioCodingModule::Codec("L16", &codec, kFsHz[n], kChannels[k]);
        acm_b_->RegisterReceiveCodec(codec);
      }
    }

    // Create and connect the channel
    channel_a2b_ = new Channel;
    acm_a_->RegisterTransportCallback(channel_a2b_);
    channel_a2b_->RegisterReceiverACM(acm_b_.get());
  }

  void NbMono() {
    CodecInst codec;
    AudioCodingModule::Codec("L16", &codec, 8000, 1);
    codec.pacsize = codec.plfreq * 30 / 1000;  // 30 ms packets.
    Run(codec, 1000);
  }

  void WbMono() {
    CodecInst codec;
    AudioCodingModule::Codec("L16", &codec, 16000, 1);
    codec.pacsize = codec.plfreq * 30 / 1000;  // 30 ms packets.
    Run(codec, 1000);
  }

  void SwbMono() {
    CodecInst codec;
    AudioCodingModule::Codec("L16", &codec, 32000, 1);
    codec.pacsize = codec.plfreq * 10 / 1000;  // 10 ms packets.
    Run(codec, 400);  // Memory constraints limit the buffer at <500 ms.
  }

  void NbStereo() {
    CodecInst codec;
    AudioCodingModule::Codec("L16", &codec, 8000, 2);
    codec.pacsize = codec.plfreq * 30 / 1000;  // 30 ms packets.
    Run(codec, 1000);
  }

  void WbStereo() {
    CodecInst codec;
    AudioCodingModule::Codec("L16", &codec, 16000, 2);
    codec.pacsize = codec.plfreq * 30 / 1000;  // 30 ms packets.
    Run(codec, 1000);
  }

  void SwbStereo() {
    CodecInst codec;
    AudioCodingModule::Codec("L16", &codec, 32000, 2);
    codec.pacsize = codec.plfreq * 10 / 1000;  // 10 ms packets.
    Run(codec, 400);  // Memory constraints limit the buffer at <500 ms.
  }

 private:
  void Run(CodecInst codec, int initial_delay_ms) {
    AudioFrame in_audio_frame;
    AudioFrame out_audio_frame;
    int num_frames = 0;
    const int kAmp = 10000;
    in_audio_frame.sample_rate_hz_ = codec.plfreq;
    in_audio_frame.num_channels_ = codec.channels;
    in_audio_frame.samples_per_channel_ = codec.plfreq / 100;  // 10 ms.
    size_t samples = in_audio_frame.num_channels_ *
        in_audio_frame.samples_per_channel_;
    for (size_t n = 0; n < samples; ++n) {
      in_audio_frame.data_[n] = kAmp;
    }

    uint32_t timestamp = 0;
    double rms = 0;
    ASSERT_EQ(0, acm_a_->RegisterSendCodec(codec));
    acm_b_->SetInitialPlayoutDelay(initial_delay_ms);
    while (rms < kAmp / 2) {
      in_audio_frame.timestamp_ = timestamp;
      timestamp += static_cast<uint32_t>(in_audio_frame.samples_per_channel_);
      ASSERT_GE(acm_a_->Add10MsData(in_audio_frame), 0);
      ASSERT_EQ(0, acm_b_->PlayoutData10Ms(codec.plfreq, &out_audio_frame));
      rms = FrameRms(out_audio_frame);
      ++num_frames;
    }

    ASSERT_GE(num_frames * 10, initial_delay_ms);
    ASSERT_LE(num_frames * 10, initial_delay_ms + 100);
  }

  rtc::scoped_ptr<AudioCodingModule> acm_a_;
  rtc::scoped_ptr<AudioCodingModule> acm_b_;
  Channel* channel_a2b_;
};

TEST_F(InitialPlayoutDelayTest, NbMono) { NbMono(); }

TEST_F(InitialPlayoutDelayTest, WbMono) { WbMono(); }

TEST_F(InitialPlayoutDelayTest, SwbMono) { SwbMono(); }

TEST_F(InitialPlayoutDelayTest, NbStereo) { NbStereo(); }

TEST_F(InitialPlayoutDelayTest, WbStereo) { WbStereo(); }

TEST_F(InitialPlayoutDelayTest, SwbStereo) { SwbStereo(); }

}  // namespace webrtc
