/*
 *  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();
}

WebRtc_Word16 
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);

    WebRtc_UWord16 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;
    WebRtc_UWord8 num_encoders = _acmReceiver->NumberOfCodecs();
    // Register all available codes as receiving codecs once more.
    for (WebRtc_UWord8 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((WebRtc_UWord8)1, codecInst);
    CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
    EncodeDecode();

    WebRtc_Word16 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((WebRtc_UWord8)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((WebRtc_UWord8)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((WebRtc_UWord8)4, codecInst);
    CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
    EncodeDecode();

    _acmLeft->Codec((WebRtc_UWord8)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;
    WebRtc_Word32 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] = (WebRtc_Word16)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] = (WebRtc_Word16)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;
    WebRtc_Word32 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
