/*
 *  Copyright (c) 2011 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 "SpatialAudio.h"
#include "utility.h"
#include "trace.h"
#include "common_types.h"

using 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_Word8 audioFileName[MAX_FILE_NAME_LENGTH_BYTE];
    WebRtc_UWord16 sampFreqHz = 32000;

    strncpy(audioFileName, "./test/data/audio_coding/testfile32kHz.pcm",
            MAX_FILE_NAME_LENGTH_BYTE - 1);
    if(_testMode == 1)
    {
        printf("Enter the input file [%s]: ", audioFileName);
        PCMFile::ChooseFile(audioFileName, MAX_FILE_NAME_LENGTH_BYTE, &sampFreqHz);
    }
    _inFile.Open(audioFileName, sampFreqHz, "rb", false);

    if(_testMode == 0)
    {
        strncpy(audioFileName, "./src/modules/audio_coding/main/test/out_spatial_autotest.pcm",
                MAX_FILE_NAME_LENGTH_BYTE - 1);
    }
    else if(_testMode == 1)
    {
        printf("\n");
        strncpy(audioFileName, "./src/modules/audio_coding/main/test/testspatial_out.pcm",
                MAX_FILE_NAME_LENGTH_BYTE - 1);
        printf("Enter the output file [%s]: ", audioFileName);
        PCMFile::ChooseFile(audioFileName, MAX_FILE_NAME_LENGTH_BYTE, &sampFreqHz);
    }
    else
    {
        strncpy(audioFileName, "./src/modules/audio_coding/main/test/testspatial_out.pcm",
                        MAX_FILE_NAME_LENGTH_BYTE - 1);
    }
    _outFile.Open(audioFileName, sampFreqHz, "wb", false);
    _outFile.SaveStereo(true);


    // Register couple of codecs as receive codec    
    CodecInst codecInst;

    _acmLeft->Codec((WebRtc_UWord8)0, codecInst);    
    codecInst.channels = 2;
    CHECK_ERROR(_acmReceiver->RegisterReceiveCodec(codecInst));

    _acmLeft->Codec((WebRtc_UWord8)3, codecInst);    
    codecInst.channels = 2;
    CHECK_ERROR(_acmReceiver->RegisterReceiveCodec(codecInst));
 
    _acmLeft->Codec((WebRtc_UWord8)1, codecInst);
    CHECK_ERROR(_acmReceiver->RegisterReceiveCodec(codecInst));
    
    _acmLeft->Codec((WebRtc_UWord8)4, codecInst);
    CHECK_ERROR(_acmReceiver->RegisterReceiveCodec(codecInst));

    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._payloadDataLengthInSamples; n++)
        {
            audioFrame._payloadData[n] = (WebRtc_Word16)floor(
                audioFrame._payloadData[n] * leftPanning + 0.5);
        }
        CHECK_ERROR(_acmLeft->Add10MsData(audioFrame));

        for(int n = 0; n < audioFrame._payloadDataLengthInSamples; n++)
        {
            audioFrame._payloadData[n] = (WebRtc_Word16)floor(
                audioFrame._payloadData[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();
}


