/*
 *  Copyright (c) 2012 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 <stdio.h>
#include <string.h>

#include <math.h>

#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/main/test/SpatialAudio.h"
#include "webrtc/system_wrappers/include/trace.h"
#include "webrtc/system_wrappers/include/trace.h"
#include "webrtc/test/testsupport/fileutils.h"

namespace webrtc {

#define NUM_PANN_COEFFS 10

SpatialAudio::SpatialAudio(int testMode)
    : _acmLeft(AudioCodingModule::Create(1)),
      _acmRight(AudioCodingModule::Create(2)),
      _acmReceiver(AudioCodingModule::Create(3)),
      _testMode(testMode) {
}

SpatialAudio::~SpatialAudio() {
  delete _channel;
  _inFile.Close();
  _outFile.Close();
}

int16_t SpatialAudio::Setup() {
  _channel = new Channel;

  // Register callback for the sender side.
  CHECK_ERROR(_acmLeft->RegisterTransportCallback(_channel));
  CHECK_ERROR(_acmRight->RegisterTransportCallback(_channel));
  // Register the receiver ACM in channel
  _channel->RegisterReceiverACM(_acmReceiver.get());

  uint16_t sampFreqHz = 32000;

  const std::string file_name = webrtc::test::ResourcePath(
      "audio_coding/testfile32kHz", "pcm");
  _inFile.Open(file_name, sampFreqHz, "rb", false);

  std::string output_file = webrtc::test::OutputPath()
      + "out_spatial_autotest.pcm";
  if (_testMode == 1) {
    output_file = webrtc::test::OutputPath() + "testspatial_out.pcm";
    printf("\n");
    printf("Enter the output file [%s]: ", output_file.c_str());
    PCMFile::ChooseFile(&output_file, MAX_FILE_NAME_LENGTH_BYTE, &sampFreqHz);
  } else {
    output_file = webrtc::test::OutputPath() + "testspatial_out.pcm";
  }
  _outFile.Open(output_file, sampFreqHz, "wb", false);
  _outFile.SaveStereo(true);

  // Register all available codes as receiving codecs.
  CodecInst codecInst;
  int status;
  uint8_t num_encoders = _acmReceiver->NumberOfCodecs();
  // Register all available codes as receiving codecs once more.
  for (uint8_t n = 0; n < num_encoders; n++) {
    status = _acmReceiver->Codec(n, &codecInst);
    if (status < 0) {
      printf("Error in Codec(), no matching codec found");
    }
    status = _acmReceiver->RegisterReceiveCodec(codecInst);
    if (status < 0) {
      printf("Error in RegisterReceiveCodec() for payload type %d",
             codecInst.pltype);
    }
  }

  return 0;
}

void SpatialAudio::Perform() {
  if (_testMode == 0) {
    printf("Running SpatialAudio Test");
    WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1,
                 "---------- SpatialAudio ----------");
  }

  Setup();

  CodecInst codecInst;
  _acmLeft->Codec((uint8_t) 1, &codecInst);
  CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
  EncodeDecode();

  int16_t pannCntr = 0;

  double leftPanning[NUM_PANN_COEFFS] = { 1.00, 0.95, 0.90, 0.85, 0.80, 0.75,
      0.70, 0.60, 0.55, 0.50 };
  double rightPanning[NUM_PANN_COEFFS] = { 0.50, 0.55, 0.60, 0.70, 0.75, 0.80,
      0.85, 0.90, 0.95, 1.00 };

  while ((pannCntr + 1) < NUM_PANN_COEFFS) {
    _acmLeft->Codec((uint8_t) 0, &codecInst);
    codecInst.pacsize = 480;
    CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
    CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst));

    EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]);
    pannCntr++;

    // Change codec
    _acmLeft->Codec((uint8_t) 3, &codecInst);
    codecInst.pacsize = 320;
    CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
    CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst));

    EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]);
    pannCntr++;
    if (_testMode == 0) {
      printf(".");
    }
  }

  _acmLeft->Codec((uint8_t) 4, &codecInst);
  CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
  EncodeDecode();

  _acmLeft->Codec((uint8_t) 0, &codecInst);
  codecInst.pacsize = 480;
  CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
  CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst));
  pannCntr = NUM_PANN_COEFFS - 1;
  while (pannCntr >= 0) {
    EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]);
    pannCntr--;
    if (_testMode == 0) {
      printf(".");
    }
  }
  if (_testMode == 0) {
    printf("Done!\n");
  }
}

void SpatialAudio::EncodeDecode(const double leftPanning,
                                const double rightPanning) {
  AudioFrame audioFrame;
  int32_t outFileSampFreq = _outFile.SamplingFrequency();

  const double rightToLeftRatio = rightPanning / leftPanning;

  _channel->SetIsStereo(true);

  while (!_inFile.EndOfFile()) {
    _inFile.Read10MsData(audioFrame);
    for (size_t n = 0; n < audioFrame.samples_per_channel_; n++) {
      audioFrame.data_[n] = (int16_t) floor(
          audioFrame.data_[n] * leftPanning + 0.5);
    }
    CHECK_ERROR(_acmLeft->Add10MsData(audioFrame));

    for (size_t n = 0; n < audioFrame.samples_per_channel_; n++) {
      audioFrame.data_[n] = (int16_t) floor(
          audioFrame.data_[n] * rightToLeftRatio + 0.5);
    }
    CHECK_ERROR(_acmRight->Add10MsData(audioFrame));

    CHECK_ERROR(_acmReceiver->PlayoutData10Ms(outFileSampFreq, &audioFrame));
    _outFile.Write10MsData(audioFrame);
  }
  _inFile.Rewind();
}

void SpatialAudio::EncodeDecode() {
  AudioFrame audioFrame;
  int32_t outFileSampFreq = _outFile.SamplingFrequency();

  _channel->SetIsStereo(false);

  while (!_inFile.EndOfFile()) {
    _inFile.Read10MsData(audioFrame);
    CHECK_ERROR(_acmLeft->Add10MsData(audioFrame));

    CHECK_ERROR(_acmReceiver->PlayoutData10Ms(outFileSampFreq, &audioFrame));
    _outFile.Write10MsData(audioFrame);
  }
  _inFile.Rewind();
}

}  // namespace webrtc
