/*
 *  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 "common_types.h"
#include "SpatialAudio.h"
#include "trace.h"
#include "testsupport/fileutils.h"
#include "utility.h"

namespace webrtc {

#define NUM_PANN_COEFFS 10

SpatialAudio::SpatialAudio(int testMode)
{
    _testMode = testMode;
}

SpatialAudio::~SpatialAudio()
{
    AudioCodingModule::Destroy(_acmLeft);
    AudioCodingModule::Destroy(_acmRight);
    AudioCodingModule::Destroy(_acmReceiver);
    delete _channel;
    _inFile.Close();
    _outFile.Close();
}

int16_t 
SpatialAudio::Setup()
{
    // Create ACMs and the Channel;
    _acmLeft = AudioCodingModule::Create(1);
    _acmRight = AudioCodingModule::Create(2);
    _acmReceiver = AudioCodingModule::Create(3);
    _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);

    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(int 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(int 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(_acmLeft->Process());
        CHECK_ERROR(_acmRight->Process());

        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(_acmLeft->Process());

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

} // namespace webrtc
