/*
 *  Copyright (c) 2014 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 "modules/audio_coding/acm2/acm_receive_test.h"

#include <stdio.h>

#include <memory>

#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "modules/audio_coding/include/audio_coding_module.h"
#include "modules/audio_coding/neteq/tools/audio_sink.h"
#include "modules/audio_coding/neteq/tools/packet.h"
#include "modules/audio_coding/neteq/tools/packet_source.h"
#include "modules/include/module_common_types.h"
#include "test/gtest.h"

namespace webrtc {
namespace test {

namespace {
AudioCodingModule::Config MakeAcmConfig(
    Clock* clock,
    rtc::scoped_refptr<AudioDecoderFactory> decoder_factory) {
  AudioCodingModule::Config config;
  config.clock = clock;
  config.decoder_factory = std::move(decoder_factory);
  return config;
}
}  // namespace

AcmReceiveTestOldApi::AcmReceiveTestOldApi(
    PacketSource* packet_source,
    AudioSink* audio_sink,
    int output_freq_hz,
    NumOutputChannels exptected_output_channels,
    rtc::scoped_refptr<AudioDecoderFactory> decoder_factory)
    : clock_(0),
      acm_(webrtc::AudioCodingModule::Create(
          MakeAcmConfig(&clock_, std::move(decoder_factory)))),
      packet_source_(packet_source),
      audio_sink_(audio_sink),
      output_freq_hz_(output_freq_hz),
      exptected_output_channels_(exptected_output_channels) {}

AcmReceiveTestOldApi::~AcmReceiveTestOldApi() = default;

void AcmReceiveTestOldApi::RegisterDefaultCodecs() {
  acm_->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
                          {104, {"ISAC", 32000, 1}},
                          {107, {"L16", 8000, 1}},
                          {108, {"L16", 16000, 1}},
                          {109, {"L16", 32000, 1}},
                          {111, {"L16", 8000, 2}},
                          {112, {"L16", 16000, 2}},
                          {113, {"L16", 32000, 2}},
                          {0, {"PCMU", 8000, 1}},
                          {110, {"PCMU", 8000, 2}},
                          {8, {"PCMA", 8000, 1}},
                          {118, {"PCMA", 8000, 2}},
                          {102, {"ILBC", 8000, 1}},
                          {9, {"G722", 8000, 1}},
                          {119, {"G722", 8000, 2}},
                          {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
                          {13, {"CN", 8000, 1}},
                          {98, {"CN", 16000, 1}},
                          {99, {"CN", 32000, 1}}});
}

// Remaps payload types from ACM's default to those used in the resource file
// neteq_universal_new.rtp.
void AcmReceiveTestOldApi::RegisterNetEqTestCodecs() {
  acm_->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
                          {104, {"ISAC", 32000, 1}},
                          {93, {"L16", 8000, 1}},
                          {94, {"L16", 16000, 1}},
                          {95, {"L16", 32000, 1}},
                          {0, {"PCMU", 8000, 1}},
                          {8, {"PCMA", 8000, 1}},
                          {102, {"ILBC", 8000, 1}},
                          {9, {"G722", 8000, 1}},
                          {120, {"OPUS", 48000, 2}},
                          {13, {"CN", 8000, 1}},
                          {98, {"CN", 16000, 1}},
                          {99, {"CN", 32000, 1}}});
}

void AcmReceiveTestOldApi::Run() {
  for (std::unique_ptr<Packet> packet(packet_source_->NextPacket()); packet;
       packet = packet_source_->NextPacket()) {
    // Pull audio until time to insert packet.
    while (clock_.TimeInMilliseconds() < packet->time_ms()) {
      AudioFrame output_frame;
      bool muted;
      EXPECT_EQ(0,
                acm_->PlayoutData10Ms(output_freq_hz_, &output_frame, &muted));
      ASSERT_EQ(output_freq_hz_, output_frame.sample_rate_hz_);
      ASSERT_FALSE(muted);
      const size_t samples_per_block =
          static_cast<size_t>(output_freq_hz_ * 10 / 1000);
      EXPECT_EQ(samples_per_block, output_frame.samples_per_channel_);
      if (exptected_output_channels_ != kArbitraryChannels) {
        if (output_frame.speech_type_ == webrtc::AudioFrame::kPLC) {
          // Don't check number of channels for PLC output, since each test run
          // usually starts with a short period of mono PLC before decoding the
          // first packet.
        } else {
          EXPECT_EQ(exptected_output_channels_, output_frame.num_channels_);
        }
      }
      ASSERT_TRUE(audio_sink_->WriteAudioFrame(output_frame));
      clock_.AdvanceTimeMilliseconds(10);
      AfterGetAudio();
    }

    EXPECT_EQ(0, acm_->IncomingPacket(
                     packet->payload(),
                     static_cast<int32_t>(packet->payload_length_bytes()),
                     packet->header()))
        << "Failure when inserting packet:" << std::endl
        << "  PT = " << static_cast<int>(packet->header().payloadType)
        << std::endl
        << "  TS = " << packet->header().timestamp << std::endl
        << "  SN = " << packet->header().sequenceNumber;
  }
}

AcmReceiveTestToggleOutputFreqOldApi::AcmReceiveTestToggleOutputFreqOldApi(
    PacketSource* packet_source,
    AudioSink* audio_sink,
    int output_freq_hz_1,
    int output_freq_hz_2,
    int toggle_period_ms,
    NumOutputChannels exptected_output_channels)
    : AcmReceiveTestOldApi(packet_source,
                           audio_sink,
                           output_freq_hz_1,
                           exptected_output_channels,
                           CreateBuiltinAudioDecoderFactory()),
      output_freq_hz_1_(output_freq_hz_1),
      output_freq_hz_2_(output_freq_hz_2),
      toggle_period_ms_(toggle_period_ms),
      last_toggle_time_ms_(clock_.TimeInMilliseconds()) {}

void AcmReceiveTestToggleOutputFreqOldApi::AfterGetAudio() {
  if (clock_.TimeInMilliseconds() >= last_toggle_time_ms_ + toggle_period_ms_) {
    output_freq_hz_ = (output_freq_hz_ == output_freq_hz_1_)
                          ? output_freq_hz_2_
                          : output_freq_hz_1_;
    last_toggle_time_ms_ = clock_.TimeInMilliseconds();
  }
}

}  // namespace test
}  // namespace webrtc
