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