/*
 *  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 "modules/audio_coding/test/opus_test.h"

#include <assert.h>

#include <string>

#include "common_types.h"  // NOLINT(build/include)
#include "modules/audio_coding/codecs/audio_format_conversion.h"
#include "modules/audio_coding/codecs/opus/opus_interface.h"
#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
#include "modules/audio_coding/test/TestStereo.h"
#include "modules/audio_coding/test/utility.h"
#include "test/gtest.h"
#include "test/testsupport/fileutils.h"
#include "typedefs.h"  // NOLINT(build/include)

namespace webrtc {

OpusTest::OpusTest()
    : acm_receiver_(AudioCodingModule::Create()),
      channel_a2b_(NULL),
      counter_(0),
      payload_type_(255),
      rtp_timestamp_(0) {}

OpusTest::~OpusTest() {
  if (channel_a2b_ != NULL) {
    delete channel_a2b_;
    channel_a2b_ = NULL;
  }
  if (opus_mono_encoder_ != NULL) {
    WebRtcOpus_EncoderFree(opus_mono_encoder_);
    opus_mono_encoder_ = NULL;
  }
  if (opus_stereo_encoder_ != NULL) {
    WebRtcOpus_EncoderFree(opus_stereo_encoder_);
    opus_stereo_encoder_ = NULL;
  }
  if (opus_mono_decoder_ != NULL) {
    WebRtcOpus_DecoderFree(opus_mono_decoder_);
    opus_mono_decoder_ = NULL;
  }
  if (opus_stereo_decoder_ != NULL) {
    WebRtcOpus_DecoderFree(opus_stereo_decoder_);
    opus_stereo_decoder_ = NULL;
  }
}

void OpusTest::Perform() {
#ifndef WEBRTC_CODEC_OPUS
  // Opus isn't defined, exit.
  return;
#else
  uint16_t frequency_hz;
  size_t audio_channels;
  int16_t test_cntr = 0;

  // Open both mono and stereo test files in 32 kHz.
  const std::string file_name_stereo =
      webrtc::test::ResourcePath("audio_coding/teststereo32kHz", "pcm");
  const std::string file_name_mono =
      webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
  frequency_hz = 32000;
  in_file_stereo_.Open(file_name_stereo, frequency_hz, "rb");
  in_file_stereo_.ReadStereo(true);
  in_file_mono_.Open(file_name_mono, frequency_hz, "rb");
  in_file_mono_.ReadStereo(false);

  // Create Opus encoders for mono and stereo.
  ASSERT_GT(WebRtcOpus_EncoderCreate(&opus_mono_encoder_, 1, 0), -1);
  ASSERT_GT(WebRtcOpus_EncoderCreate(&opus_stereo_encoder_, 2, 1), -1);

  // Create Opus decoders for mono and stereo for stand-alone testing of Opus.
  ASSERT_GT(WebRtcOpus_DecoderCreate(&opus_mono_decoder_, 1), -1);
  ASSERT_GT(WebRtcOpus_DecoderCreate(&opus_stereo_decoder_, 2), -1);
  WebRtcOpus_DecoderInit(opus_mono_decoder_);
  WebRtcOpus_DecoderInit(opus_stereo_decoder_);

  ASSERT_TRUE(acm_receiver_.get() != NULL);
  EXPECT_EQ(0, acm_receiver_->InitializeReceiver());

  // Register Opus stereo as receiving codec.
  CodecInst opus_codec_param;
  int codec_id = acm_receiver_->Codec("opus", 48000, 2);
  EXPECT_EQ(0, acm_receiver_->Codec(codec_id, &opus_codec_param));
  payload_type_ = opus_codec_param.pltype;
  EXPECT_EQ(true,
            acm_receiver_->RegisterReceiveCodec(
                opus_codec_param.pltype, CodecInstToSdp(opus_codec_param)));

  // Create and connect the channel.
  channel_a2b_ = new TestPackStereo;
  channel_a2b_->RegisterReceiverACM(acm_receiver_.get());

  //
  // Test Stereo.
  //

  channel_a2b_->set_codec_mode(kStereo);
  audio_channels = 2;
  test_cntr++;
  OpenOutFile(test_cntr);

  // Run Opus with 2.5 ms frame size.
  Run(channel_a2b_, audio_channels, 64000, 120);

  // Run Opus with 5 ms frame size.
  Run(channel_a2b_, audio_channels, 64000, 240);

  // Run Opus with 10 ms frame size.
  Run(channel_a2b_, audio_channels, 64000, 480);

  // Run Opus with 20 ms frame size.
  Run(channel_a2b_, audio_channels, 64000, 960);

  // Run Opus with 40 ms frame size.
  Run(channel_a2b_, audio_channels, 64000, 1920);

  // Run Opus with 60 ms frame size.
  Run(channel_a2b_, audio_channels, 64000, 2880);

  out_file_.Close();
  out_file_standalone_.Close();

  //
  // Test Opus stereo with packet-losses.
  //

  test_cntr++;
  OpenOutFile(test_cntr);

  // Run Opus with 20 ms frame size, 1% packet loss.
  Run(channel_a2b_, audio_channels, 64000, 960, 1);

  // Run Opus with 20 ms frame size, 5% packet loss.
  Run(channel_a2b_, audio_channels, 64000, 960, 5);

  // Run Opus with 20 ms frame size, 10% packet loss.
  Run(channel_a2b_, audio_channels, 64000, 960, 10);

  out_file_.Close();
  out_file_standalone_.Close();

  //
  // Test Mono.
  //
  channel_a2b_->set_codec_mode(kMono);
  audio_channels = 1;
  test_cntr++;
  OpenOutFile(test_cntr);

  // Register Opus mono as receiving codec.
  opus_codec_param.channels = 1;
  EXPECT_EQ(true,
            acm_receiver_->RegisterReceiveCodec(
                opus_codec_param.pltype, CodecInstToSdp(opus_codec_param)));

  // Run Opus with 2.5 ms frame size.
  Run(channel_a2b_, audio_channels, 32000, 120);

  // Run Opus with 5 ms frame size.
  Run(channel_a2b_, audio_channels, 32000, 240);

  // Run Opus with 10 ms frame size.
  Run(channel_a2b_, audio_channels, 32000, 480);

  // Run Opus with 20 ms frame size.
  Run(channel_a2b_, audio_channels, 32000, 960);

  // Run Opus with 40 ms frame size.
  Run(channel_a2b_, audio_channels, 32000, 1920);

  // Run Opus with 60 ms frame size.
  Run(channel_a2b_, audio_channels, 32000, 2880);

  out_file_.Close();
  out_file_standalone_.Close();

  //
  // Test Opus mono with packet-losses.
  //
  test_cntr++;
  OpenOutFile(test_cntr);

  // Run Opus with 20 ms frame size, 1% packet loss.
  Run(channel_a2b_, audio_channels, 64000, 960, 1);

  // Run Opus with 20 ms frame size, 5% packet loss.
  Run(channel_a2b_, audio_channels, 64000, 960, 5);

  // Run Opus with 20 ms frame size, 10% packet loss.
  Run(channel_a2b_, audio_channels, 64000, 960, 10);

  // Close the files.
  in_file_stereo_.Close();
  in_file_mono_.Close();
  out_file_.Close();
  out_file_standalone_.Close();
#endif
}

void OpusTest::Run(TestPackStereo* channel, size_t channels, int bitrate,
                   size_t frame_length, int percent_loss) {
  AudioFrame audio_frame;
  int32_t out_freq_hz_b = out_file_.SamplingFrequency();
  const size_t kBufferSizeSamples = 480 * 12 * 2;  // 120 ms stereo audio.
  int16_t audio[kBufferSizeSamples];
  int16_t out_audio[kBufferSizeSamples];
  int16_t audio_type;
  size_t written_samples = 0;
  size_t read_samples = 0;
  size_t decoded_samples = 0;
  bool first_packet = true;
  uint32_t start_time_stamp = 0;

  channel->reset_payload_size();
  counter_ = 0;

  // Set encoder rate.
  EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_mono_encoder_, bitrate));
  EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_stereo_encoder_, bitrate));

#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) || defined(WEBRTC_ARCH_ARM)
  // If we are on Android, iOS and/or ARM, use a lower complexity setting as
  // default.
  const int kOpusComplexity5 = 5;
  EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_mono_encoder_, kOpusComplexity5));
  EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_stereo_encoder_,
                                        kOpusComplexity5));
#endif

  // Fast-forward 1 second (100 blocks) since the files start with silence.
  in_file_stereo_.FastForward(100);
  in_file_mono_.FastForward(100);

  // Limit the runtime to 1000 blocks of 10 ms each.
  for (size_t audio_length = 0; audio_length < 1000; audio_length += 10) {
    bool lost_packet = false;

    // Get 10 msec of audio.
    if (channels == 1) {
      if (in_file_mono_.EndOfFile()) {
        break;
      }
      in_file_mono_.Read10MsData(audio_frame);
    } else {
      if (in_file_stereo_.EndOfFile()) {
        break;
      }
      in_file_stereo_.Read10MsData(audio_frame);
    }

    // If input audio is sampled at 32 kHz, resampling to 48 kHz is required.
    EXPECT_EQ(480,
              resampler_.Resample10Msec(audio_frame.data(),
                                        audio_frame.sample_rate_hz_,
                                        48000,
                                        channels,
                                        kBufferSizeSamples - written_samples,
                                        &audio[written_samples]));
    written_samples += 480 * channels;

    // Sometimes we need to loop over the audio vector to produce the right
    // number of packets.
    size_t loop_encode = (written_samples - read_samples) /
        (channels * frame_length);

    if (loop_encode > 0) {
      const size_t kMaxBytes = 1000;  // Maximum number of bytes for one packet.
      size_t bitstream_len_byte;
      uint8_t bitstream[kMaxBytes];
      for (size_t i = 0; i < loop_encode; i++) {
        int bitstream_len_byte_int = WebRtcOpus_Encode(
            (channels == 1) ? opus_mono_encoder_ : opus_stereo_encoder_,
            &audio[read_samples], frame_length, kMaxBytes, bitstream);
        ASSERT_GE(bitstream_len_byte_int, 0);
        bitstream_len_byte = static_cast<size_t>(bitstream_len_byte_int);

        // Simulate packet loss by setting |packet_loss_| to "true" in
        // |percent_loss| percent of the loops.
        // TODO(tlegrand): Move handling of loss simulation to TestPackStereo.
        if (percent_loss > 0) {
          if (counter_ == floor((100 / percent_loss) + 0.5)) {
            counter_ = 0;
            lost_packet = true;
            channel->set_lost_packet(true);
          } else {
            lost_packet = false;
            channel->set_lost_packet(false);
          }
          counter_++;
        }

        // Run stand-alone Opus decoder, or decode PLC.
        if (channels == 1) {
          if (!lost_packet) {
            decoded_samples += WebRtcOpus_Decode(
                opus_mono_decoder_, bitstream, bitstream_len_byte,
                &out_audio[decoded_samples * channels], &audio_type);
          } else {
            decoded_samples += WebRtcOpus_DecodePlc(
                opus_mono_decoder_, &out_audio[decoded_samples * channels], 1);
          }
        } else {
          if (!lost_packet) {
            decoded_samples += WebRtcOpus_Decode(
                opus_stereo_decoder_, bitstream, bitstream_len_byte,
                &out_audio[decoded_samples * channels], &audio_type);
          } else {
            decoded_samples += WebRtcOpus_DecodePlc(
                opus_stereo_decoder_, &out_audio[decoded_samples * channels],
                1);
          }
        }

        // Send data to the channel. "channel" will handle the loss simulation.
        channel->SendData(kAudioFrameSpeech, payload_type_, rtp_timestamp_,
                          bitstream, bitstream_len_byte, NULL);
        if (first_packet) {
          first_packet = false;
          start_time_stamp = rtp_timestamp_;
        }
        rtp_timestamp_ += static_cast<uint32_t>(frame_length);
        read_samples += frame_length * channels;
      }
      if (read_samples == written_samples) {
        read_samples = 0;
        written_samples = 0;
      }
    }

    // Run received side of ACM.
    bool muted;
    ASSERT_EQ(
        0, acm_receiver_->PlayoutData10Ms(out_freq_hz_b, &audio_frame, &muted));
    ASSERT_FALSE(muted);

    // Write output speech to file.
    out_file_.Write10MsData(
        audio_frame.data(),
        audio_frame.samples_per_channel_ * audio_frame.num_channels_);

    // Write stand-alone speech to file.
    out_file_standalone_.Write10MsData(out_audio, decoded_samples * channels);

    if (audio_frame.timestamp_ > start_time_stamp) {
      // Number of channels should be the same for both stand-alone and
      // ACM-decoding.
      EXPECT_EQ(audio_frame.num_channels_, channels);
    }

    decoded_samples = 0;
  }

  if (in_file_mono_.EndOfFile()) {
    in_file_mono_.Rewind();
  }
  if (in_file_stereo_.EndOfFile()) {
    in_file_stereo_.Rewind();
  }
  // Reset in case we ended with a lost packet.
  channel->set_lost_packet(false);
}

void OpusTest::OpenOutFile(int test_number) {
  std::string file_name;
  std::stringstream file_stream;
  file_stream << webrtc::test::OutputPath() << "opustest_out_"
      << test_number << ".pcm";
  file_name = file_stream.str();
  out_file_.Open(file_name, 48000, "wb");
  file_stream.str("");
  file_name = file_stream.str();
  file_stream << webrtc::test::OutputPath() << "opusstandalone_out_"
      << test_number << ".pcm";
  file_name = file_stream.str();
  out_file_standalone_.Open(file_name, 48000, "wb");
}

}  // namespace webrtc
